發表文章

目前顯示的是 4月, 2011的文章

使用T4範本產生器讀取資料庫時指定所要使用的SMO版本

圖片
在使用T4範本產生器讀取資料庫的資訊時,一般可能都會用如下的引用方式: <#@ template language="C#" debug="True" hostspecific="True" encoding="0"#> <#@ output extension=".cs" #> <#@ assembly name="System.Data" #> <#@ assembly name="Microsoft.SqlServer.ConnectionInfo" #> <#@ assembly name="Microsoft.SqlServer.Smo" #> <#@ assembly name="Microsoft.SqlServer.Management.Sdk.Sfc" #> <#@ assembly name="System.Xml" #> <#@ import namespace="System.IO" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Data.SqlClient" #> <#@ import namespace="Microsoft.SqlServer.Management.Smo" #> <#@ import namespace="Microsoft.SqlServer.Management.Common" #> 其中在引用有關 M icrosoft® SQL Server® 2008 R2 共用管理物件 時,大部份都直接寫Assembly的名稱。但是如果您的開發環境中安裝了兩種以上的SQL Server版本時,這時會取用註冊在GAC中的哪一種版本,可能就會取決於您目前所使用的Visu

將資料表中某欄位值串接成字串

圖片
今天在逛網站時,突然看到有人在介紹SQL Server新的T-SQL指令PIVOT。大致上就瞭解及試了一下這種PIVOT的用途。在試過語法後,發現要使用PIVOT語法時,必須明確地知道所需要的橫向欄位有多少。 例如: -- Pivot table with one row and five columns SELECT 'AverageCost' AS Cost_Sorted_By_Production_Days, [0], [1], [2], [3], [4] FROM (SELECT DaysToManufacture, StandardCost     FROM Production.Product) AS SourceTable PIVOT ( AVG(StandardCost) FOR DaysToManufacture IN ([0], [1], [2], [3], [4]) ) AS PivotTable; 這個來 自MSDN上的PIVOT範例 。執行結果如下: 由上面的範例來看,PIVOT可以將原本是直行的查詢結果,轉換成橫向的查詢結果。不過,這樣的語法使用上就是必須事先知道所要的橫向欄位有哪些。如果一開始不確定PIVOT中要的橫向欄位有哪些的話,那該如何是好。 最好的方式就是這些橫向欄位是可以由另外一份清單來取得。不過,在PIVOT中它無法再支援子查詢的方式,也就是不能寫成: PIVOT ( AVG(StandardCost) FOR DaysToManufacture IN ( select * FROM xxxx ) ) AS PivotTable; 可能的作法就是要自已動態組合SQL指令,再來執行了。執行的方式可以用: execute sp_executesql @SQLCmd 如何組合出動態PIVOT橫向欄位 在網路上找到一篇有關 如何將資料表中的資料組成一組串列 的方式,不過,這篇文章中的組合方式好像有點問題。那篇文章中作者使用到 COALESCE() 這個T-SQL指令。COALESCE()指令的用法是將兩個參數中不為NULL的那個傳回。最後組出來的字串中,第一個字串前面也會多了一個','。所以我就改寫了一下語法,不使用COALESCE()

C# Controls相關文章

EasyProgressBar

自訂Wordpress右邊日曆小工具樣式

圖片
最近在設定我的Wordpress網站時,找到一個不錯的佈景主題(Theme):Ramiro。套用後大致上的樣式都OK,但就是右邊有設定的「日曆」小工具會超出原本佈景主題所設定的範圍。 當然Wordpress有支援可以在管理介面中去修改這些Theme的樣式。一開始想說是不是在一些控製邊欄的.php檔中。可是找了一下,也沒有找到。去查了一下Wordpress有關Theme製作上,如果要顯示這個日曆的話,好像是要用get_calendar()的函式。可是發現我使用的Theme中並沒有呼叫到這個函式。 後來沒辦法,想說那不然就直接看看網頁的原始程式碼好了。 發現原來在這個區域是屬於「right」所控管的。所以就到這個佈景主題的樣式表中去查詢。發現是有這個ID,但裏面並沒有特別去控制日曆相關的樣式。也就是沒有去設定以下這些ID的樣式: calendar_wrap wp-calendar 我猜想應該是沿用了「right」區的字型造成日曆的顯示超出邊界了。於是就開始動手加入有關上述這兩個ID的樣式表。 最主要的改善方式就是將字型由1.5em改為0.5em。這樣就可以了。 不過,上面這樣看起來有點美中不足的就是整個日曆有點偏右。沒關係,只要再加上margin : -10px。就好了:

研究Wordpress的主題製作

Wordpress的主題製作除了使用許多的CSS外,另一部份就是要動態地由資料庫中查詢所以的資料來呈現。這些查詢的功能在Wordpress中叫作 Template Tag 。

VS2010目前還無法開發ReportingService專案

原本想說安裝了VS2010,再安裝SQL Server 2008 R2 Express(ADV)版後,就可以在VS2010中開發Reporting Service的報表專案了。沒想到目前 VS2010還未整合Reporting Service 的部份。所以暫時是不可行的了。還是得用VS2008來進行開發。

實作資料表分割

圖片
當某個資料表中的資料快速累積到一定程度時,對這樣龐大的資料表進行查詢或新增、刪除等動作都會相當地費時。如果能將這個資料表分割成數個區塊來進行查詢及維護,對效能應該會有所幫助。 在SQL Server 2008以前要實作出資料表分割的概念的話,可能就是真的要建立數個不同名稱,但具有相同的資料表表網的資料表。並利用某個預先定義好的分割函式來將資料表中的內容加以分割,放置到個別的資料表中。 要查詢時,再利用View的方式JOIN成一個資料表檢視來進行查詢。或是在查詢前利用相同的資料分割函式決定出要查詢的區塊,再到那個區塊所對應的資料表中進行查詢。不過,這種方式都是需要使用者能明確地事先依資料分割函式來計算所要取用的資料區塊才行。 在SQL Server 2008版中,它真接內建了 資料表分割的功能 。只要您提供所需的 資料表分割函式 ,以及 資料表分割表綱(SCHEMA) ,就可以將資料表進行分割了。 要實作資料表分割的話,如果您一開始還沒有建好資料表,那當然可以先建好資料表分割函式、資料表分割表綱後再來建立資料表。不過,如果要針對既有的資料表進行資料表分割的話,應該也是有相對應的SQL指令可以來完成,但在SQL Server 2008的管理工具中已經有提供介面化的方式來讓您為即有的資料表進行資料表分割的設定。 以下說明如何利用SQL Server管理工具的介面來進行資料表分割。 首先找到您要進行分割的資料表,在這個資料表上按下右鍵,會出現一個選單,其中有一項是:儲存體。在儲存體中有個「建立資料分割」的功能,這個功能就是用來製作分割資料表的工具。 一開始會出現說明的畫面: 接著會出現這個資料表的所有欄位資訊,主要就是要選定一個欄位來作為資料表分割的依據。 選好欄位後,接下來就是要提供用來分割資料用的函式。這個函式可以新增,或是利用原本來已經產生好的函式也可以。 接著就是要指定所要使用的資料表分割表綱: 選好資料表分割表網後,會出現一個設定檔案群組的介面。在這個介面中是指定用所選的資料表分割表綱中每個分割區塊所要放置的檔案群組。檔案群組可以都放在同一個,或是都各自給一個不同的檔案群組。在此我採用的方式是將舊資料表放到一個新增的檔案群組中。而將目前會使用到的資料則維持在預設的PRIMARY檔案群組中。 一切都設定好後

用DataBaseMail寄件時使用Global Temporary Table

圖片
有時候我們會需要建立一個資料庫排程來檢查資料庫中的某些資料是否存在,當有問題時,可以利用DataBaseMail的方式來寄送警告信件。 不過,在寄件時有時又需要將查詢到的資訊附件信件中。雖然在用DataBaseMail寄信時可以指定要使用一段SQL指令查詢資料並作為信件內容。但在這段查詢指令中,並無法使用暫存表。正確來說是無法使用Local Temporary Table。 例如以下的方式是在將查詢的結果儲存到Local Temporary Table (#tmp)中,並試著在寄送mail時將這個暫存表的內容附加到mail中。結果就出現錯誤訊息:無效的物件名稱#tmp。這是因為在寄送mail時,它執行的是另一段session,在其它的session中是無法看到目前session中的暫存表的。 為了要在寄送mail時可使用到原本session中的查詢結果,我們改用Global Temporary Table(##tmp),這樣就可以正常寄送mail了。

VS2010好用套件

圖片
Indent Guide:讓程式碼中的縮排能自動配對顯示

設定資料表分割表綱時出現錯誤訊息

我要新增一個資料表,並指定使用分割資料表模式時,語法如下: CREATE TABLE xxxx ON PartitionSchema 結果出現如下的錯誤訊息: 訊息 2726,層級 16,狀態 1,行 2 資料分割函數 'StatusSplitFunc_3' 使用 1 個資料行,這和用於分割資料表或索引的資料分割資料行數目不符。 查了一下沒有看到有人有過這樣的錯誤訊息。後來才知道,原來是在ON 的後面的分割資料表表網中,要指定所要使用的參數。 例如: ON PartitionSchema(txdate)這樣。

解決未取消Event註冊時造成物件無法被回收的議題

當我們將A物件的某函式掛勾到B物件的某個事件上時,如果沒有將B物件的事件函式中有關A物件的掛勾關聯取消的話,就算A物件已不在可用範圍,需要被進行回收的話,因為它還存在著B物件對它的參考,會造成A物件一直無法被回收。也就是所謂的memory leaking。 要解決這個問題,可以參考: Simple effective Weak Event Dispatcher in C#
在一台Window Server 2008 x64上安裝的 SQL 2008 R2 x64資料庫中,要利用遠端連接的方式去查詢一台較古老的SQL 2000的資料庫時,雖然有設定好遠端連接伺服器,但還是出現了以下的錯誤訊息: 連結伺服器 "xxx" 的 OLE DB 提供者 "SQLNCLI10" 傳回訊息 "無法指出的錯誤"。 連結伺服器 "xxx" 的 OLE DB 提供者 "SQLNCLI10" 傳回訊息 "無法在伺服器中找到完成此操作所須的預存程序。請連絡您的系統管理員。"。 訊息 7311,層級 16,狀態 2,行 1 無法為連結伺服器 "xxxx" 的 OLE DB 提供者 "SQLNCLI10" 取得結構描述資料列集 "DBSCHEMA_TABLES_INFO"。提供者支援介面,但在使用時傳回失敗碼。 查了一下,有人說要在SQL 2000上昇級到SP3或SP4。但我看昇級的部份已經有了。後來才知道原來昇級完後,還要 自行執行預存程序的昇級動作 才行。 我使用的方式是在SQL 2000的本機上執行以下的指令: osql -E -S 10.6.xx.xx -i "C:\Program Files\Microsoft SQL Server\MSSQL\Install\instcat.sql" 其中要指定的就是原本SQL 2000的IP位址。這樣就可以正常查詢了。

SQL Profiler應用

最近因為資料庫的效能出現瓶頸,所以開始學習用 SQL Profiler來記錄某段時間的資料庫使用狀況。只是SQL Profiler記錄下來的資料有一大堆,要如何從中找出感興趣的部份,也是一件要學習的工作了。 用SQL Profiler記錄下來的資料,可以先儲存成檔案,副檔名為.trc。再 將它匯入到資料表 中。用如下的指令: SELECT * INTO trace1108 FROM ::fn_trace_gettable('E:\Test.trc', default) 因為已經匯入成資料表了,所以要查詢所需的資訊就可以用SQL指令來進行查詢。 不過要注意幾點: 1) Duration的單位 在SQL Profiler中所顯示的Duration單位是千分之一秒,而用儲存過的檔案匯入到資料表中所用的單位是百萬分之一秒。 2) 在EventClass這欄原本SQL Profiler中顯示的是文字資料,但匯入到資料表後所使用的是原本的 分類代碼 。是整數的資料。

批次設定執行預存程序的權限給特定使用者

圖片
最近在更動資料庫的權限設定,發現有個帳號的權限設成是 db_owner,所以它有權限可以新增、刪除資料庫裏的資料表。權限有點過大。所以就將它改成只有db_datareader及db_datawriter的權限。 但後來發現原本這組帳號也需要可以執行所有的預存程序。一但改為只有db_datareader及db_datawriter的話,就沒有權限可以去執行預存程序了。但如果要透過MS SQL管理介面來設定的話,又要一個個進去設定,相當費時間。 於是就開始尋找看是否有T-SQL的指令可以批次來設定預存程序的執行權限給某組帳號。發現MS SQL本身並沒有函式可用來批次設定。但找到有一位提供的解答是 用T-SQL指令來產生所需的GRANT指令 。 大致上的方式是用查詢資料庫預設資料表 INFORMATION_SCHEMA.ROUTINES 來找出目前使用的資料庫中所建立的所有預存程序資訊。 可以用如下的指令來產生所需的T-SQL指令: SELECT 'GRANT EXEC ON ' + QUOTENAME(ROUTINE_NAME) + ' TO ' FROM INFORMATION_SCHEMA.ROUTINES 不過,後來發現並不是所有的預存程序都可以指定EXEC的權限,有些預存程序如果是函數型,且傳回值為一個TABLE的話,那這種預存程序就只能指定授權SELECT的權限而已。 所以比較正確的指令應該是如下。分成兩種模式。一種是授權EXEC;另一種授權SELECT。 SELECT 'GRANT EXEC ON ' + QUOTENAME(ROUTINE_NAME) + ' TO user-account' FROM INFORMATION_SCHEMA.ROUTINES where DATA_TYPE <> 'TABLE' OR DATA_TYPE is NULL SELECT 'GRANT SELECT ON ' + QUOTENAME(ROUTINE_NAME) + ' TO user-account' FROM INFORMATION_SCHEMA.ROUTINES where DA