Saving and Retrieving Images From SQL Server Using DAAB and ADO.NET 2.0

Saving and Retrieving Images From SQL Server Using DAAB

An interesting question in my Inbox about how to save and retrieve images using the Enterprise Library 2.0 Data Access Application Block ( DAAB ) and SQL Server.

I am not sure using DAAB changes the code all that much, since most of the code is really converting images to byte arrays and vice versa.

I, honestly, don’t store images in SQL Server, because if you serve up those images a lot I think you may experience a performance hit in your applications. My gut says that streaming large binary images across a tier ( database to webserver for example ) quite often will make your application less scalable and just plain slow. However, if those images are small and/or you incorporate the right amount of caching, you certainly can get away with it. And, of course, if the application is small, you can do just about anything :)

I did some searching and I couldn’t find a good example on saving images to SQL Server, so here is my take on a good way to do it. This example is using SQL Server 2000 and the Image Data Type. In SQL Server 2005 you would use the VARBINARY(MAX) Data Type as the Image Data Type is no longer preferred in SQL Server 2005.

Saving Image to SQL Server

Retrieving an image from the hard disk and inserting it into SQL Server using DAAB:

byte[] image;

string fileName = @"c:\davidhayden.jpg";

// Open File and Read Into Byte Array
using (FileStream fs =
new FileStream(fileName, FileMode.Open))
{
BinaryReader reader = new BinaryReader(fs);
image = reader.ReadBytes((int)fs.Length);
fs.Close();
}

// Get Database
Database db = DatabaseFactory.CreateDatabase();

// Create DbCommand
string insertSql = “INSERT INTO Photos (Photo)
VALUES (@Photo)";
DbCommand command = db.GetSqlStringCommand(insertSql);
db.AddInParameter(command,"@Photo",DbType.Binary,image);

// Store Image
int rowsAffected = db.ExecuteNonQuery(command);

Retrieving Image from SQL Server

Retrieving the image from SQL Server:

// Get Database
Database db = DatabaseFactory.CreateDatabase();

// Create Example DbCommand
string selectSql = “SELECT Photo FROM Photos
WHERE PhotoID = 1″;
DbCommand selectCommand =
db.GetSqlStringCommand(selectSql);

// Execute Command
byte[] storedImage = (byte[])db.
ExecuteScalar(selectCommand);

// Convert byte[] to Image
Image newImage;
using (MemoryStream stream =
new MemoryStream(storedImage))
{
newImage = Image.FromStream(stream);
}

// Display to make sure code works
pictureBox1.Image = newImage;

FileUpload Control and VB Example

If you are loading the picture from a FileUpload Control in a web page, the code will be slightly different. Here is the same example of saving the image to SQL Server using a FileUpload Control and VB:

Protected Sub Button1_Click(ByVal sender As Object,
ByVal e As System.EventArgs) Handles Button1.Click

If FileUpload1.HasFile Then

Dim reader As BinaryReader =
New BinaryReader(FileUpload1.
PostedFile.InputStream)

Dim image() As Byte =
reader.ReadBytes(FileUpload1.
PostedFile.ContentLength)

Dim db As Database =
DatabaseFactory.CreateDatabase()

Dim insertSql As String =
“INSERT INTO Photos (Photo) VALUES (@Photo)"
Dim command As DbCommand =
db.GetSqlStringCommand(insertSql)
db.AddInParameter(command, “@Photo",
Data.DbType.Binary, image)

Dim rowsAffected As Integer =
db.ExecuteNonQuery(command)

End If
End Sub

Conclusion

Storing Image in SQL Server using System.Data.SqlClient wouldn’t really be that much different. Hopefully this helps.

Source: David Hayden ( .NET Developer )

Filed: Enterprise Library 2.0, ADO.NET 2.0, SQL Server

Saving and Displaying Photos in SQL Server using ASP.NET

Saving and Displaying Photos in SQL Server using ASP.NET and FileUpload Control

Saving Photo in SQL Server Using SqlClient

Rather than using the Enterprise Library Data Access Application Block, let’s use the SQL Server .NET Managed Provider to store photos uploaded via a FileUpload Control in ASP.NET.

The code is very simple as shown below:

protected void Button1_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
using (BinaryReader reader = new BinaryReader
(FileUpload1.PostedFile.InputStream))
{
byte[] image = reader.ReadBytes
(FileUpload1.PostedFile.ContentLength);
SaveImage(image);
}
}
}

private int SaveImage(byte[] image)
{
int rowsAffected;

using (SqlConnection connection = new SqlConnection(“…“))
{
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = “INSERT INTO Photos
(Photo) VALUES (@Photo)";
command.Parameters.AddWithValue(“@Photo", image);

connection.Open();
rowsAffected = command.ExecuteNonQuery();
}
}

return rowsAffected;
}

Once the user clicks a button, the code verifies that the FileUpload Control indeed has a photo. The photo is converted to a byte array for storage in SQL Server. In SQL Server 2000, the photo will be stored as an Image DataType. In SQL Server 2005, the photo will be stored in the preferred VARBINARY(MAX) DataType. At this point, the database connection is opened and the code executes an INSERT T-SQL Statement that stores the photo as a byte array ( byte[] ) into SQL Server.

Display Photo In SQL Server Using ASP.NET

Displaying the photo in SQL Server using ASP.NET is just as easy. Just reverse the process as shown in the code below:

protected void Page_Init(object sender, EventArgs e)
{
if (Request.QueryString[“id"] != null)
{
int id;

if (Int32.TryParse(Request.QueryString[“id"], out id))
{
Response.Clear();
Response.ContentType = “image/jpeg";

Image image = RetrieveImage(id);
image.Save(Response.OutputStream, ImageFormat.Jpeg);
}
}
}

private Image RetrieveImage(int photoId)
{
Image image = null;

using (SqlConnection connection = new SqlConnection(“…"))
{
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = “SELECT Photo FROM Photos
WHERE PhotoId = @PhotoId";
command.Parameters.AddWithValue(“@PhotoId", photoId);

connection.Open();
byte[] imageData = (byte[])command.ExecuteScalar();

MemoryStream memStream = new MemoryStream(imageData);
image = Image.FromStream(memStream);
}
}

return image;
}

The photo id is read in from a querystring. If it parses correctly, the response buffer is cleared and reset to display a photo as opposed to HTML. The photo is read from the SQL Server Database as a byte array and it gets converted to a System.Drawing.Image with a little help from the MemoryStream Class. I recommend adding a bit of exception handling, but assuming the photo exists, the code works fine by displaying the appropriate image in the browser window.

Source: David Hayden ( ASP.NET Developer )

Filed: ADO.NET Tutorials

Guita, 美國牛仔音樂的節奏及彈奏技巧

Guita, 美國牛仔音樂的節奏及彈奏技巧 – AAA 小喇叭 – 小喇叭 – Yahoo! BLOG

GOOGLE 是無限的免費資源, 替小老外找 CANON 的鋼琴譜時, 無意中看到這個教人彈奏 banjo 的 youtube,

http://www.youtube.com/user/ezfolk777#p/u/7/GWaW4C5z_Ek

終於看到原來西部電影的音樂特色如何來的, 有空就來試試看這種技巧

他稱為 BUM DITTY……初時聽還以為是 BUM DADDY……

Base64 encoder, 小工具

Base64 encoder, 小工具 – AAA 小喇叭 – 小喇叭 – Yahoo! BLOG

Base64 encoder, 小工具
網誌分類:AAA 你都可以 DIY |
圖片
網誌日期:2010-05-18 18:40
用 Telnet Login ESMTP 需要 Base64 Encode 的密碼及帳號, 可能有人問如何做.

可以找 ONLINE 版的, 不過通常麻煩又慢. 所以干脆自己寫了一個小工具, 安心又簡單,SOURCE CODE 有附. MASM32 源碼, EXE 都一並提供

http://www.mediafire.com/file/nlynwx4ztjj/base64en.zip (大約 7.8K)

http://sourceforge.net/projects/base64-encoder/files/

用 Telnet 發送 email 的步驟 (Windows)

[開始] -> [執行] -> 輸入 cmd, 然後按 ENTER, 有個黑色背景的 DOS BOX 出來, C:\… 後面有一格下橫線畫線在閃閃閃, 如果是, 這個就是 DOS BOX

接著在 DOS BOX 內輸入 telnet smtp.mail.yahoo.com 587, 然後按 ENTER……再看看有沒有出現 220 …………………..等字樣…確認過 PCCW 把所有 SMTP.NETVIGATOR.COM PORT 25 以外的連接都過濾.

據網友的提示, 確認過, GMAIL / YAHOO 可以這樣連接,
telnet smtp.mail.yahoo.com 587
telnet smtp.gmail.com 587

SSL (未試驗)
telnet smtp.mail.yahoo.com 465
telnet smtp.gmail.com 465

其他的參考前面兩個紀錄

http://hk.myblog.yahoo.com/xiao-laba/article?mid=2649

http://hk.myblog.yahoo.com/xiao-laba/article?mid=2643

Base64 的簡介

http://zh.wikipedia.org/zh-hk/Base64
引用(0)
網誌標籤:Base64 encoder, 小工具

Skype/VoIP phone adapter

Skype VoIP phone adapter (last update: 26 may 2008)

It’s free and open project was created and shared to find cheap method of using VoIP with old or new wired or wireless phones. You can publish it anywhere if it may be useful to people.

Just imagine: You can walk with your wireless phone chatting with Skype friends for free (for unlimited traffic), you can make free call to your mom if she is connected to the Internet. You can make your telephone network with servises, voicemail, etc and chat there using your old phone. Skype wireless phones are expensive, VoIP adapters cost ~$60, but you can make it for free if your have details.. from old TV, Radio or other electronics.

● News
● Schematics
● Using Skype
● Using Xlite
● Using Trixbox (Asterisk@Home) – own PBX (phonestation)
● Comments
● Pictures, video
● Feedback

DIY 把市話轉接到 SKYPE, 繳電費比中華電信的轉接費便宜很多 – AAA 小喇叭 – 小喇叭 – Yahoo! BLOG

辦公室的業務員永遠外出, 而市話的來電必須轉接到手機, 所以平均每人每月因為這樣的轉接要額外增加最少 NT$2000 起碼.

中華電信的市話接到手機, 其實就是用家裡的固網電話, 直接撥號到指定的手機號碼, 再把來電者的線路接通, 那來電者就和手機受話端通話, 最便宜大約 NT$5 一分鐘 (降價時段已經是晚上, 每人辦公, 不列如考慮之列)
http://www.cht.com.tw/PersonalCat.php?Module=Fee,Describe&CatID=113&PageID=1694

按照台灣電力公司的公告, 現在的電費是 NT$2.5840 / kWh

http://www.taipower.com.tw/left_bar/QnA/electrical_bill_idea.htm

所以, NT$2000 大概是 1000 度電力費用, 或是少於400分鐘通話費

假設網機器和電腦長開, 總計每天 24 小時 x 50W / 小時 = 1200W = 1.2 度

每月 30 個工作天, 總計每月耗電 1.2 kWh x 30 = 36 度電力 = NT$93

所以, 只要把市話來電轉接到網路電話 (行動3G), 自然就可以節省開銷近20倍, 因為就算沒有這樣的設計, 每人還是會用3G上網吃到飽的月租計畫, 辦公室還是會有光纖上網的月租費.

Welcome to Mobile Atlas Creator

Mobile Atlas Creator

Welcome to Mobile Atlas Creator

Mobile Atlas Creator (formerly known as TrekBuddy Atlas Creator) is an open source (GPL) program which creates offline atlases for GPS handhelds and cell phone applications like TrekBuddy, AndNav and other Android and WindowsCE based applications. For the full list of supported applications please see the features section. Additionally individual maps can be exported as one large PNG image with calibration MAP file for OziExplorer. As source for an offline atlas Mobile Atlas Creator can use a large number of different online maps such as OpenStreetMap, Google Maps, Microsoft/Bing Maps, Yahoo Maps and many more online map providers.

淺談 SQL Server 2005 T-SQL新功能

資訊櫥窗

1 契子

Transact Structure Query Language(T-SQL) 結構化查詢語言是與 SQL Server 溝通的基礎,一切的指令對資料庫引擎而言最終都要以 T-SQL 呈 現。SQL Server 2005 大幅增加了新功能,當然也需要大幅擴增 T-SQL 語言
以操控這些功能,增加執行效率與錯誤處理的機制,同時為了提供程式開 發的能力,T-SQL 舊有的語法也加以翻新,透過更豐富的選項來呈現 SQL Server 2005。

T-SQL語言有兩種主要的區分:資料定義語言 (Data Definition Language,DDL),用於定義與管理所有 SQL 資料庫物件;而資料操作語言 (Data Manipulation Language,DML),是用於選取、插入、更新與刪除使用 DDL 所定義的物件中的資料。用於管理資料庫、資料表與檢視表等物件的 Transact-SQL DDL 是以具延伸的 SQL-92 DDL 陳述式為基礎。這次Microsoft在SQL Server 2005中對於DDL與DML中新增了許多以往大型資料庫系統才有的功能,雖然這些功能對於資料庫系統不算新的觀念,但都僅存於大型資料庫系統,Microsoft這次將不但這些功能囊括進來並加以改良,看得出Microsoft要搶佔資料庫市場的決心,我們就來看看Microsoft新增了哪些功能。

2 資料定義語言(Data Definition Language DDL)

2.1 新的資料型態

SQL Server 2005 針對於字串與XML的儲存提供了新的資料型態,其內容表列如下: VARCHAR(MAX)/NVARCHAR(MAX)/VARBINARY(MAX):當宣告了 MAX 關鍵字,該欄位最多可以存放 2Giga (2^31-1)位元組的資料。而不再受限於以往的 8K(也就是 Page 的大小)。這三種資料型態可以用來取代 text、ntext 以及 image 等資料型態。由 SQL Server 自行決定存放大型資料的方式,而不需我們事先決定要用指標結構存放 text 一類的資料,還是一般的 char 等資料格式。而以 VARCHAR(MAX)/NVARCHAR(MAX) 取代 text、ntext 最大的好處在於一般的 T-SQL 字串處理函數都可以操作 VARCHAR(MAX)/NVARCHAR(MAX) 欄位內的資料,而不像 text、ntext 會讓很多函數無法使用。

XML:原生的 XML 資料型態,可以提供 XML 資料驗證、查詢、更新、建立索引等等。該型態的資料最大長度也是 2 Giga 位元組。

2.2 索引(Index)

索引為維護是保持SQL Server效能的重要工作之一,以往許多要藉助系統預存程序、DBCC 等命令才能完成這些工作,在SQL Server2005中對此做了改良,T-SQL 的 DDL 對維護索引有更完備的語法,改以 CREATE、ALTER、DROP等標準語法來完成,讓 T-SQL 的語法更一致化,例如重建索引或去除不連續的資料不像以往需藉助 DBCC 指令。
EX: ALTER 語法新增 DISABLE 選項,可以停掉 SQL Server 對某個索引的維護與使用。

2.3 切割資料表(Partition Table)

SQL Server 2005新增一個專為大型資料庫提供的 Partition Table機制,
切割程式功能與資料一直是設計大型系統時所必備的技巧,避免使用一個小功能,卻需要啟動一個大物件,或是存取局部的資料卻需要在資料海中撈針。

在以往 SQL Server 2000 版本對於超大的資料紀錄集合可以借助於 Partition View,並在新增、修改和刪除資料時,以 Instead of Trigger 來簡化管理與開發的複雜度。但畢竟多個資料表會讓安全設定、限制式(Constraint)、索引與資料維護等等日常工作變得複雜。並在資料表新增與刪除大量紀錄時耗費交易紀錄(Transaction Log)。

在 SQL Server 2005 除了新增了 Partition Table 來提供相似的功能,更進一步地隱藏了結構上的差異,簡化切割資料後造成資料庫設計、管理、維護與使用上的不便。
Partition Table除了對於系統開發與資料管理極有幫助,佈署在多CPU主機還藉平行運算技術提高系統效能,例如:透過多顆 CPU 對多個 Partition 做平行運算,讓資料表分散存取,都將可提升存取的效能。

2.4 DDL 觸發程序

觸發程序(Trigger)以往用在特定的物件上,例如資料表或檢視表,當資料維護語言(DML)的 Insert、Delete、Update 語法針對這些物件運作時,由系統自動呼叫對應的觸發程序,而在 SQL Server 2000 版本時還增加了 Instead of Trigger,透過觸發程序取代原本要執行的新增、修改、刪除語法。

SQL Server 2005 擴增了觸發程序的應用面,加入資料定義語言(DDL)觸發程序功能。針對 DDL 語法的執行也可以啟動觸發程序,你可用來追蹤與監控資料庫架構的變化,例如新增、修改或刪除資料表時,紀錄是誰在何時對哪些資料表的定義做了什麼樣的更動。

你可能針對資料庫等級的語法觸發 DDL 觸發程序,例如 CREATE_TABLE。也可以是伺服器等級的語法,如CREATE_LOGIN。透過在觸發程序內執行ROLLBACK TRANSACTION 語法能夠將原來使用者執行的 DDL回復,就如同沒有執行該語法。與 DML 觸發程序相同的是:執行一句 DDL 可能同時觸發多個 DDL 觸發程序,但我們無法掌控其執行順序,所以 DDL 觸發程序間不能有先後的依存關係。

3 資料維護語言(Data Manipulation Language DML)

3.1 Common Table Expression(CTE)

Common table expression(CTE) 可以視之為暫存的檢視表,其功能相當於檢視表(View) 但它的生命週期僅存取單一次的 T-SQL 批次(batch)語法中,而不似一般的暫存物件其生命週期與連線(connection)同在,同時兼具View和衍生資料表(Derived table)的能力。

因為生命週期僅存取單一次的 T-SQL 批次(batch)語法中,所以定義與使用需要在相同批次中一起執行,執行完該批次後,CTE 物件立刻失效。

3.2 取得排名或順序的函數

以往我們僅能使用ORDER BY語法對查詢出來的結果進行排序,在SQL Server 2005中新增了數個關於紀錄在資料集合中的順序(Ranking)之函數,使用OVER 子句搭配RANK、DENSE_RANK、ROW_NUMBER 和 NTILE等函數,可以達到進階的資料排續結果,其功能如下:

RANK 在結果集中每一筆紀錄所在的排名位置,但排名可能不連續,例如若有兩個第一名,則下一個名次直接跳至第三名。

DENSE_RANK 功能與 RANK 相似,但代表排名的數值是連續的。

ROW_NUMBER 依照群組呈現每一筆紀錄在該群中出現的順序位置。

NTILE 依照指定的分群數量將結果集切分(partition),並呈現紀錄在各群的排名位置。
除此之外,還可使用PARTITION BY 子句將查詢結果進行分群,若省略了 PARITITION BY 子句則視全部的紀錄為一群。

3.3 結構化錯誤處理

在SQL Server 2000以前的版本,錯誤處理的結構過於簡單,在撰寫較為複雜的預存程序時,無法建立完善的錯誤處理機制,許多錯誤是無法透過錯誤處理機制來改善的。,總是令開發人員頗為困擾。其錯誤處理的結構 SQL Server 2005 提供了類似 C++ 或 .NET 語法的 TRY…CATCH 機 制,讓我們在撰寫 T-SQL 程式時也可以做結構化錯誤處理,減少程式寫作 的複雜性並提升程式碼的可讀性;也就提升了程式碼的可維護性與穩定 性。

3.4 APPLY 運算子

APPLY 運算子是 SQL Server 2005 新增的。讓 SELECT 查詢語法可與 傳回資料表的函數(table-valued function TVF)做進一步的結合。例如:這在資料 表含有 XML 欄位時,結合 XML 的內容轉換為新的資料表欄位頗為方便。 APPLY 運算子讓每一筆紀錄都呼叫一次 TVF,並將結果與原資料表的內 容一起展開。 APPLY 定義在查詢的 FROM 子句內,其格式有兩種型態:CROSS APPLY和 OUTER APPLY。兩者的差異與使用方式與 JOIN 運算子類似。

CROSS APPLY:只在當外部的資料表逐筆紀錄帶入到 TVF 之後,若 TVF 並無符合的紀錄傳回來,則運算將不會呈現該筆紀錄。

OUTER APPLY:依然會展現外部資料表對應的紀錄,但 TVF 相關的欄位則以 NULL 呈現。

3.5 Pivot 和 UnPivot 語法

Pivot 語法提供類似樞紐分析表的功能,讓一筆筆的紀錄可以某個欄位轉成各欄,並在欄列交錯的各資料格填入彙總的值,一般也稱這種的查詢方式為 crosstab 查詢,也就是 MS Access 提供之 TRANSFORM 語法的功能。

3.6 Output 語法

OUTPUT 子句是SQL Server 2005為 INSERT、DELETE、UPDATE 所 新增的。在 INSERT、DELETE、UPDATE 語法中現在可以搭配 OUTPUT 子句,引用以往在寫 Trigger 時相同的特殊系統資料表 INSERTED 和 DELETED。

3.7 宣告參照完整性功能的增強

Integrity Constraints 在關聯式資料庫中是很重要的觀念。根據ANSI SQL-92標準對於外鍵(Foreign Key)限制式(Constraint)在修改資料時;定義了四種因應方式:
财 set NULL:即當ParentTable中刪除或修改一筆資料時,Foreign Table上的資料是設為NULL。
财 set Default:設Foreign Key為Default Value。
财 Cascade:即當刪除或修改Parent Table時,對Foreign Table也做同樣的刪除或修改。
财 No Action:即當此筆資料存在有Foreign Key時,不允許做刪除或修改。

SQL Server 2000 版本只支援了兩種:No Action和Cascade更新。在 SQL Server 2005 則對 DELETE和 UPDATE 再增加了 SET DEFAULT 和 SET NULL 兩種功能。

4 後記

Microsoft 將SQL Server 2005定位為下一代的資料管理和分析軟體,在千呼萬喚下,目前也只釋出Beta 2,其新增功能當然不僅於此,本文僅針對T-SQL做粗淺的介紹,至於其它的創新改良如:商業智慧功能、、Data Mining演算法、報表服務等,則留待來日再做說明。

參考文獻
1. http://www.dbworld.com.tw/
2. http://www.microsoft.com/taiwan/sql/