顯示具有 SQL 標籤的文章。 顯示所有文章
顯示具有 SQL 標籤的文章。 顯示所有文章

2017年8月25日 星期五

SQL 資料轉 INSERT 語法-使用 Visual Studio

將資料表內容轉成一連串 INSERT 語法,是蠻好用的跨伺服器搬資料表招式,之前我最愛用的工具是 SQL Dumper,但昨天聽到不幸消息:官方網站人去樓空,連註冊的 DNS 網域都已棄守。
重新尋找替代方案,找到三種做法:
  1. SSMS 內建 Generate Script 功能
  2. SSMS Tools Pack
  3. SQL Server Data Tools in VS2015+


原始介紹文章出自於此

2017年8月2日 星期三

SQLQueryStress, Stress testing, 壓力測試

SQLQueryStress 是 SQL Server 壓力測試工具,無須安裝 Portable Edition

同樣是由 sp_whoisactive 作者 - Adam Machanic 所開發,目前已釋出到開源專案平臺 GitHub 上。真的很感謝 Adam 大師提供許多好用的工具給 DBA,以及 ErikEJ 大師的更新維護。

SQLQueryStress 在使用上 無須安裝,且檔案輕巧(約 745 KB - Version 0.9.7.53)。這是在執行壓力測試時的好工具。


下載 SQLQueryStress

下載 最新版本:SQLQueryStress Version 0.9.7.53

The latest build for the application has been released by @ErikEJ which contains changes related to IO reads on Temp and Global Temp tables. https://ci.appveyor.com/api/projects/ErikEJ/SqlQueryStress/artifacts/SqlQueryStress.zip?branch=master

原始介紹文章出自於此


[SQL Server] Stress testing, SQLQueryStress parameter, 壓力測試, 搭配使用 參數 (2)

2016年7月14日 星期四

微軟認證考試心得:Exam 70-461 - Query MicroSoft SQL Server 2012

要取得 MCSA 資格,必須通過 70-461, 462, 463,接著才能再往上取得 MCSE 與 MCSM。

一般而言,開發人員(Dev)可以取得70-461認證,而資料庫管理師(DBA)適合考取 70-462,倉儲管理師可考取70-463。

這三類考試不分先後順序取得認證資格。



其他介紹內容請到原文章觀看

2016年3月8日 星期二

將複合字串拆成多欄位-以ORACLE及SQL為例



ORACLE

-- :pFindKey = 'FBI-IT01-12345'
--方法1
select * from BLAH where OrgId || '-' || DeptId || '-' || UserId = :pFindKey
--方法2
select * from BLAH where 
       OrgtId = REGEXP_SUBSTR(:pFindKey, '[^-]+', 1, 1) and
       DeptId = REGEXP_SUBSTR(:pFindKey, '[^-]+', 1, 2) and
       UserId = REGEXP_SUBSTR(:pFIndKey, '[^-]+', 1, 3)




SQL Server

declare @pFindKey varchar(32) 
set @pFindKey = 'FBI-IT1-12345'
--方法1
select * from BLAH where OrgId + '-' + DeptId + '-' + UserId = @pFindKey
--方法2
select BLAH.* from BLAH
join (select convert(xml, '<n>' + replace(@pFindKey, '-','</n><n>') + '</n>') as x) Keys
on OrgId = Keys.x.value('(/n)[1]', 'varchar(16)') and 
   DeptId = Keys.x.value('(/n)[2]', 'varchar(16)') and 
   UserId = Keys.x.value('(/n)[3]', 'varchar(16)')


原始介紹文章出自於此

2016年2月4日 星期四

LINQ寫法:類SQL查詢語法 vs 方法串接

記得在LINQ剛推出時以「可以在C#裡寫SQL語法查資料」為號召,範例裡常看到這種長得有點像SQL語法的LINQ查詢運算式(LINQ Query Expression,我習慣叫它「類SQL查詢語法」):
排版顯示純文字
    IEnumerable<int> scoreQuery = //query variable
        from score in scores //required
        where score > 80 // optional
        orderby score descending // optional
        select score; //must end with select or group
 
不過,我在熟悉LINQ後(甚至演變成「少了LINQ幾乎不會寫程式」),卻很少再用這種寫法,大都是用LINQ方法配上Lambda運算式:
排版顯示純文字
    IEnumerable<int> scoreQuery = //query variable
        scores //required
        .Where(o => o.score > 80) // optional
        .OrderByDescending(o => o.score) // optional
        .Select(o => o.score); //must end with select or group
 
那一種寫法比較好?好問題,甚至我也想不起來自己選擇第二種寫法的理由。既然聊到了,順手對二者做了粗淺的分析比較。
首先,有一個重要觀念:兩種寫法編譯出來的結果是相同的!





原始介紹文章出自於此

2015年11月12日 星期四

找出SQL Server效能問題

下面是我個人從網路蒐集來的TSQL,透過這些TSQL發現SQL Server效能問題真的相當實用且快速

--find out current blocked object
use yourdb
go
select
    OBJECT_NAME(p.[object_id]) BlockedObject
    ,st.text as SqlStatementText
    ,waitstats.wait_duration_ms
    ,waitstats.wait_type
    ,waitstats.resource_description
from    sys.dm_exec_connections as blocking
    join sys.dm_exec_requests as blocked
        ON blocking.session_id = blocked.blocking_session_id
    join sys.dm_os_waiting_tasks as waitstats
        ON waitstats.session_id = blocked.session_id
    join sys.partitions as p ON SUBSTRING(resource_description,
        PATINDEX('%associatedObjectId%', resource_description) + 19,
        LEN(resource_description)) = p.partition_id
    cross apply sys.dm_exec_sql_text(blocked.sql_handle) as st

--find out parallelism
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
WITH XMLNAMESPACES 
   (DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
select
        query_plan AS CompleteQueryPlan,
        n.value('(@StatementText)[1]', 'VARCHAR(4000)') AS StatementText,
        n.value('(@StatementOptmLevel)[1]', 'VARCHAR(25)') AS StatementOptimizationLevel,
        n.value('(@StatementSubTreeCost)[1]', 'VARCHAR(128)') AS StatementSubTreeCost,
        n.query('.') AS ParallelSubTreeXML,
        ecp.usecounts,
        ecp.size_in_bytes
from sys.dm_exec_cached_plans AS ecp
cross apply sys.dm_exec_query_plan(plan_handle) AS eqp
cross apply query_plan.nodes('/ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple') AS qn(n)
where  n.query('.').exist('//RelOp[@PhysicalOp="Parallelism"]') = 1

--find out TempDB contention
Select session_id,
wait_type,
wait_duration_ms,
blocking_session_id,
resource_description,
      ResourceType = Case
When Cast(Right(resource_description, Len(resource_description) - Charindex(':', resource_description, 3)) As Int) - 1 % 8088 = 0 Then 'Is PFS Page'
            When Cast(Right(resource_description, Len(resource_description) - Charindex(':', resource_description, 3)) As Int) - 2 % 511232 = 0 Then 'Is GAM Page'
            When Cast(Right(resource_description, Len(resource_description) - Charindex(':', resource_description, 3)) As Int) - 3 % 511232 = 0 Then 'Is SGAM Page'
            Else 'Is Not PFS, GAM, or SGAM page'
            End
From sys.dm_os_waiting_tasks
Where wait_type Like 'PAGE%LATCH_%'
And resource_description Like '2:%'


--find out I/O specific waits
WITH Waits AS
(SELECT wait_type, wait_time_ms / 1000. AS wait_time_s,
100. * wait_time_ms / SUM(wait_time_ms) OVER() AS pct,
ROW_NUMBER() OVER(ORDER BY wait_time_ms DESC) AS rn
FROM sys.dm_os_wait_stats
WHERE wait_type NOT IN ('CLR_SEMAPHORE','LAZYWRITER_SLEEP','RESOURCE_QUEUE','SLEEP_TASK'
,'SLEEP_SYSTEMTASK','SQLTRACE_BUFFER_FLUSH','WAITFOR', 'LOGMGR_QUEUE','CHECKPOINT_QUEUE'
,'REQUEST_FOR_DEADLOCK_SEARCH','XE_TIMER_EVENT','BROKER_TO_FLUSH','BROKER_TASK_STOP'
,'CLR_MANUAL_EVENT','CLR_AUTO_EVENT','DISPATCHER_QUEUE_SEMAPHORE'
, 'FT_IFTS_SCHEDULER_IDLE_WAIT','XE_DISPATCHER_WAIT', 'XE_DISPATCHER_JOIN'))
SELECT W1.wait_type,
CAST(W1.wait_time_s AS DECIMAL(12, 2)) AS wait_time_s,
CAST(W1.pct AS DECIMAL(12, 2)) AS pct,
CAST(SUM(W2.pct) AS DECIMAL(12, 2)) AS running_pct
FROM Waits AS W1
INNER JOIN Waits AS W2
ON W2.rn <= W1.rn
GROUP BY W1.rn, W1.wait_type, W1.wait_time_s, W1.pct
HAVING SUM(W2.pct) - W1.pct < 95;


--get wait statistics
WITH [Waits] AS
    (SELECT
        [wait_type],
        [wait_time_ms] / 1000.0 AS [WaitS],
        ([wait_time_ms] - [signal_wait_time_ms]) / 1000.0 AS [ResourceS],
        [signal_wait_time_ms] / 1000.0 AS [SignalS],
        [waiting_tasks_count] AS [WaitCount],
        100.0 * [wait_time_ms] / SUM ([wait_time_ms]) OVER() AS [Percentage],
        ROW_NUMBER() OVER(ORDER BY [wait_time_ms] DESC) AS [RowNum]
    FROM sys.dm_os_wait_stats
    WHERE [wait_type] NOT IN (
        N'BROKER_EVENTHANDLER',             N'BROKER_RECEIVE_WAITFOR',
        N'BROKER_TASK_STOP',                N'BROKER_TO_FLUSH',
        N'BROKER_TRANSMITTER',              N'CHECKPOINT_QUEUE',
        N'CHKPT',                           N'CLR_AUTO_EVENT',
        N'CLR_MANUAL_EVENT',                N'CLR_SEMAPHORE',
        N'DBMIRROR_DBM_EVENT',              N'DBMIRROR_EVENTS_QUEUE',
        N'DBMIRROR_WORKER_QUEUE',           N'DBMIRRORING_CMD',
        N'DIRTY_PAGE_POLL',                 N'DISPATCHER_QUEUE_SEMAPHORE',
        N'EXECSYNC',                        N'FSAGENT',
        N'FT_IFTS_SCHEDULER_IDLE_WAIT',     N'FT_IFTSHC_MUTEX',
        N'HADR_CLUSAPI_CALL',               N'HADR_FILESTREAM_IOMGR_IOCOMPLETION',
        N'HADR_LOGCAPTURE_WAIT',            N'HADR_NOTIFICATION_DEQUEUE',
        N'HADR_TIMER_TASK',                 N'HADR_WORK_QUEUE',
        N'KSOURCE_WAKEUP',                  N'LAZYWRITER_SLEEP',
        N'LOGMGR_QUEUE',                    N'ONDEMAND_TASK_QUEUE',
        N'PWAIT_ALL_COMPONENTS_INITIALIZED',
        N'QDS_PERSIST_TASK_MAIN_LOOP_SLEEP',
        N'QDS_CLEANUP_STALE_QUERIES_TASK_MAIN_LOOP_SLEEP',
        N'REQUEST_FOR_DEADLOCK_SEARCH',     N'RESOURCE_QUEUE',
        N'SERVER_IDLE_CHECK',               N'SLEEP_BPOOL_FLUSH',
        N'SLEEP_DBSTARTUP',                 N'SLEEP_DCOMSTARTUP',
        N'SLEEP_MASTERDBREADY',             N'SLEEP_MASTERMDREADY',
        N'SLEEP_MASTERUPGRADED',            N'SLEEP_MSDBSTARTUP',
        N'SLEEP_SYSTEMTASK',                N'SLEEP_TASK',
        N'SLEEP_TEMPDBSTARTUP',             N'SNI_HTTP_ACCEPT',
        N'SP_SERVER_DIAGNOSTICS_SLEEP',     N'SQLTRACE_BUFFER_FLUSH',
        N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
        N'SQLTRACE_WAIT_ENTRIES',           N'WAIT_FOR_RESULTS',
        N'WAITFOR',                         N'WAITFOR_TASKSHUTDOWN',
        N'WAIT_XTP_HOST_WAIT',              N'WAIT_XTP_OFFLINE_CKPT_NEW_LOG',
        N'WAIT_XTP_CKPT_CLOSE',             N'XE_DISPATCHER_JOIN',
        N'XE_DISPATCHER_WAIT',              N'XE_TIMER_EVENT')
    AND [waiting_tasks_count] > 0
)
SELECT
    MAX ([W1].[wait_type]) AS [WaitType],
    CAST (MAX ([W1].[WaitS]) AS DECIMAL (16,2)) AS [Wait_S],
    CAST (MAX ([W1].[ResourceS]) AS DECIMAL (16,2)) AS [Resource_S],
    CAST (MAX ([W1].[SignalS]) AS DECIMAL (16,2)) AS [Signal_S],
    MAX ([W1].[WaitCount]) AS [WaitCount],
    CAST (MAX ([W1].[Percentage]) AS DECIMAL (5,2)) AS [Percentage],
    CAST ((MAX ([W1].[WaitS]) / MAX ([W1].[WaitCount])) AS DECIMAL (16,4)) AS [AvgWait_S],
    CAST ((MAX ([W1].[ResourceS]) / MAX ([W1].[WaitCount])) AS DECIMAL (16,4)) AS [AvgRes_S],
    CAST ((MAX ([W1].[SignalS]) / MAX ([W1].[WaitCount])) AS DECIMAL (16,4)) AS [AvgSig_S]
FROM [Waits] AS [W1]
INNER JOIN [Waits] AS [W2]
    ON [W2].[RowNum] <= [W1].[RowNum]
GROUP BY [W1].[RowNum]
HAVING SUM ([W2].[Percentage]) - MAX ([W1].[Percentage]) < 95; -- percentage threshold
GO


原始文章出自於此

2013年7月11日 星期四

好用的 CONVERT 日期函數






Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AM
Select CONVERT(varchar(100), GETDATE(), 1): 05/16/06
Select CONVERT(varchar(100), GETDATE(), 2): 06.05.16
Select CONVERT(varchar(100), GETDATE(), 3): 16/05/06
Select CONVERT(varchar(100), GETDATE(), 4): 16.05.06
Select CONVERT(varchar(100), GETDATE(), 5): 16-05-06
Select CONVERT(varchar(100), GETDATE(), 6): 16 05 06
Select CONVERT(varchar(100), GETDATE(), 7): 05 16, 06
Select CONVERT(varchar(100), GETDATE(), 8): 10:57:46
Select CONVERT(varchar(100), GETDATE(), 9): 05 16 2006 10:57:46:827AM
Select CONVERT(varchar(100), GETDATE(), 10): 05-16-06
Select CONVERT(varchar(100), GETDATE(), 11): 06/05/16
Select CONVERT(varchar(100), GETDATE(), 12): 060516
Select CONVERT(varchar(100), GETDATE(), 13): 16 05 2006 10:57:46:937
Select CONVERT(varchar(100), GETDATE(), 14): 10:57:46:967
Select CONVERT(varchar(100), GETDATE(), 20): 2006-05-16 10:57:47
Select CONVERT(varchar(100), GETDATE(), 21): 2006-05-16 10:57:47.157
Select CONVERT(varchar(100), GETDATE(), 22): 05/16/06 10:57:47 AM
Select CONVERT(varchar(100), GETDATE(), 23): 2006-05-16
Select CONVERT(varchar(100), GETDATE(), 24): 10:57:47
Select CONVERT(varchar(100), GETDATE(), 25): 2006-05-16 10:57:47.250
Select CONVERT(varchar(100), GETDATE(), 100): 05 16 2006 10:57AM
Select CONVERT(varchar(100), GETDATE(), 101): 05/16/2006
Select CONVERT(varchar(100), GETDATE(), 102): 2006.05.16
Select CONVERT(varchar(100), GETDATE(), 103): 16/05/2006
Select CONVERT(varchar(100), GETDATE(), 104): 16.05.2006
Select CONVERT(varchar(100), GETDATE(), 105): 16-05-2006
Select CONVERT(varchar(100), GETDATE(), 106): 16 05 2006
Select CONVERT(varchar(100), GETDATE(), 107): 05 16, 2006
Select CONVERT(varchar(100), GETDATE(), 108): 10:57:49
Select CONVERT(varchar(100), GETDATE(), 109): 05 16 2006 10:57:49:437AM
Select CONVERT(varchar(100), GETDATE(), 110): 05-16-2006
Select CONVERT(varchar(100), GETDATE(), 111): 2006/05/16
Select CONVERT(varchar(100), GETDATE(), 112): 20060516
Select CONVERT(varchar(100), GETDATE(), 113): 16 05 2006 10:57:49:513
Select CONVERT(varchar(100), GETDATE(), 114): 10:57:49:547
Select CONVERT(varchar(100), GETDATE(), 120): 2006-05-16 10:57:49
Select CONVERT(varchar(100), GETDATE(), 121): 2006-05-16 10:57:49.700
Select CONVERT(varchar(100), GETDATE(), 126): 2006-05-16T10:57:49.827
Select CONVERT(varchar(100), GETDATE(), 130): 18 ???? ?????? 1427 10:57:49:907AM
Select CONVERT(varchar(100), GETDATE(), 131): 18/04/1427 10:57:49:920AM



原始文章出自於此


2013年5月28日 星期二

SQL Server 效能優化精選

#1 SQL Server 線上叢書 - 進階 Database Engine 詳細資料了解 SQL Server 內部組成、架構、運作方式。


#2 The SQL Server Query Optimizer介紹 SQL Server 執行查詢最重要的元件 -- 查詢最佳化工具 (Query Optimizer) 的運作過程。


#3 Technical Articles - SQL Server Optimization從優化索引的面向論述如何提升查詢效能。


#4 Microsoft patterns & practices - How To: Optimize SQL Queries簡單介紹優化 SQL 查詢的工具及基本技巧,雖是以 SQL 2000 為主但很多基本概念至今仍然實用。


#5 TechNet Magazine - 最佳化 SQL Server 查詢效能 (DBA等級)解說查詢計畫 (Query Plan) 怎麼看,如何分析執行步驟,以及如何找出應該微調的查詢。本文較適合DBA或擁有充足資料庫知識的人員閱讀。


#6 MSDN Magazine - 揭露隱藏的資料以最佳化應用程式效能 (DBA等級)深入探討發生效能緩慢原因,利用 SQL Server 2005 以後內建的動態管理檢視表 (DMV) 找出各種高成本的查詢,加以進一步因應。本文較適合DBA或擁有充足資料庫知識的人員閱讀。


#7 SQL Server Query Optimization Tips作者提供許多常見的查詢技巧,大家在工作上遇到或可酌予參考應用。



以上,建議閱讀順序由上而下,#5 跟 #6 個人認為屬專業 DBA 範圍,非專職 DBA 能看懂表示平常有花時間鑽研 SQL Server 技術,若在閱讀過程無法理解也不必太灰心,建議暫時略過或私下討論;第 7 篇放在最後算是一個總結,12 道提示可當大原則應用在工作上。


原始介紹文章出自於此







2012年12月10日 星期一

SQL - DB 中,所有資料表的資料總筆數


USE AdventureWorks;

SELECT S.NAME '結構描述', O.NAME '資料表名稱', P.ROWS '列總數'
FROM SYS.OBJECTS O INNER JOIN SYS.SCHEMAS S
ON O.SCHEMA_ID = S.SCHEMA_ID
INNER JOIN SYS.PARTITIONS P
ON O.OBJECT_ID = P.OBJECT_ID
WHERE (O.TYPE = 'U') AND
(P.INDEX_ID IN (0,1))
ORDER BY S.NAME, O.NAME ASC;




原始文章出自於此


2012年11月27日 星期二

檢查資料庫中那些表格欄位可能包含身分證字號

紀錄一下實作過程
問題描述
稽核來檢查了,新版個資法上路在測試環境的個資要做遮蔽,想要知道資料庫中那些表格欄位可能包含身分證字號?
解決方式
建立CRL function來檢查資料庫那些欄位可能是身分證字號
建立方式參照自己的資料




2012年8月8日 星期三

SQL Server 2005 - 如何讓 SELECT 查詢結果額外增加自動遞增序號


USE 北風貿易;
GO

/* 方法一*/

SELECT 序號=(SELECT COUNT(客戶編號)FROM 客戶ASLiMing
                 WHERE LiMing.客戶編號<=Chang.客戶編號),
       客戶編號, 公司名稱
FROM 客戶ASChang ORDER BY 1;
GO

/* 方法二: 使用SQL Server 2005 獨有的RANK() OVER () 語法*/
SELECT RANK() OVER (ORDER BY 客戶編號DESC) AS 序號,
         客戶編號, 公司名稱
FROM 客戶;
GO

/* 方法三*/
SELECT 序號=COUNT(*), LiMing.客戶編號,LiMing.公司名稱
   FROM 客戶ASLiMing, 客戶ASChang
   WHERE LiMing.客戶編號>=Chang.客戶編號
   GROUP BY LiMing.客戶編號,LiMing.公司名稱
   ORDER BY 序號;
GO

/* 方法四
建立一個「自動編號」的欄位,然後將資料新增至一個區域性暫存資料表,
然後由該區域性暫存資料表中,將資料選取出來,最後刪除該區域性暫存資料表
*/
SELECT 序號= IDENTITY(INT,1,1), 管道, 程式語言, 講師, 資歷
INTO #LiMing
FROM 問券調查一;
GO
SELECT * FROM #LiMing;
GO
DROP TABLE #LiMing;
GO

/*
方法五
使用SQL Server 2005 獨有的ROW_NUMBER() OVER () 語法
搭配CTE (一般資料表運算式,就是WITH 那段語法)選取序號2 ~ 4 的資料
*/
WITH 排序後的圖書 AS
  (SELECT ROW_NUMBER() OVER (ORDER BY 客戶編號DESC)AS 序號,
   客戶編號, 公司名稱
   FROM 客戶)
SELECT* FROM 排序後的圖書
WHERE 序號BETWEEN2 AND 4;
GO


原始文章出自於此

2012年2月20日 星期一

SQL Server 效能優化精選

這幾天為了跟同事分享資料庫效能相關主題,花了點時間收集文件,在此貼文以饗同好!

#1 SQL Server 線上叢書 - 進階 Database Engine 詳細資料了解 SQL Server 內部組成、架構、運作方式。

#2 The SQL Server Query Optimizer介紹 SQL Server 執行查詢最重要的元件 -- 查詢最佳化工具 (Query Optimizer) 的運作過程。

#3 Technical Articles - SQL Server Optimization從優化索引的面向論述如何提升查詢效能。

#4 Microsoft patterns & practices - How To: Optimize SQL Queries簡單介紹優化 SQL 查詢的工具及基本技巧,雖是以 SQL 2000 為主但很多基本概念至今仍然實用。

#5 TechNet Magazine - 最佳化 SQL Server 查詢效能 (DBA等級)解說查詢計畫 (Query Plan) 怎麼看,如何分析執行步驟,以及如何找出應該微調的查詢。本文較適合DBA或擁有充足資料庫知識的人員閱讀。

#6 MSDN Magazine - 揭露隱藏的資料以最佳化應用程式效能 (DBA等級)深入探討發生效能緩慢原因,利用 SQL Server 2005 以後內建的動態管理檢視表 (DMV) 找出各種高成本的查詢,加以進一步因應。本文較適合DBA或擁有充足資料庫知識的人員閱讀。

#7 SQL Server Query Optimization Tips作者提供許多常見的查詢技巧,大家在工作上遇到或可酌予參考應用。


以上,建議閱讀順序由上而下,#5 跟 #6 個人認為屬專業 DBA 範圍,非專職 DBA 能看懂表示平常有花時間鑽研 SQL Server 技術,若在閱讀過程無法理解也不必太灰心,建議暫時略過或私下討論;第 7 篇放在最後算是一個總結,12 道提示可當大原則應用在工作上。


原始文章出自於此




2012年1月9日 星期一

利用SqlDataReader進行批次查詢

寫過ADO.Net的朋友們都知道,應用程式中若想連接SQL Server,單純只顯示資料給使用者,那麼利用SqlDataReader來處理會是最好的選擇。就理論而言它的效能會比SqlDataAdapter來的好,而SqlDataReader無法直接產生執行個體,必須藉由SqlCommand的ExecuteReader方法產生。若您有批次查詢的需求,可以利用SqlDataReader來處理。
假設你是使用下列的方式來查詢資料,那麼必須在每次SqlDataReader使用完畢之後利用Close方法關閉它,才能繼續給下一個SqlCommand來使用(如第16列)。

   1:  //準備連線字串
   2:  SqlConnectionStringBuilder SqlConStrBud = new SqlConnectionStringBuilder();
   3:  SqlConStrBud.DataSource = ".";
   4:  SqlConStrBud.InitialCatalog = "Northwind";
   5:  SqlConStrBud.IntegratedSecurity = true;
   6:  
   7:  using (SqlConnection SqlCon = new SqlConnection(SqlConStrBud.ToString()))
   8:  {
   9:      string strSQL = "select * from Orders;";                                   
  10:      using (SqlCommand SqlCmd = new SqlCommand(strSQL, SqlCon))
  11:      {
  12:          if (SqlCon.State != ConnectionState.Open) SqlCon.Open();
  13:          SqlDataReader SqlReader = SqlCmd.ExecuteReader();
  14:          gvOrders.DataSource = SqlReader;
  15:          gvOrders.DataBind();
  16:          SqlReader.Close();
  17:  
  18:          SqlCmd.CommandText = "select * from [Order Details];";
  19:          SqlReader = SqlCmd.ExecuteReader();
  20:          gvOrderDetails.DataSource = SqlReader;
  21:          gvOrderDetails.DataBind();
  22:          SqlReader.Close();
  23:      }
  24:  }

您可以把批次查詢所要用到的T-SQL一次設定給SqlCommand的CommandText屬性,每個查詢之間利用分號(;)隔開,並利用SqlDataReader的NextResult方法來取得下一個結果集,如此一來就不需對SqlDataReader開開關關,而且T-SQL也可以集中在同一個地方來撰寫(如第列),筆者是認為這樣的寫法比較方便維護。

   1:  //準備連線字串
   2:  SqlConnectionStringBuilder SqlConStrBud = new SqlConnectionStringBuilder();
   3:  SqlConStrBud.DataSource = ".";
   4:  SqlConStrBud.InitialCatalog = "Northwind";
   5:  SqlConStrBud.IntegratedSecurity = true;
   6:  
   7:  using (SqlConnection SqlCon = new SqlConnection(SqlConStrBud.ToString()))
   8:  {
   9:      string strSQL = "select * from Orders;"
  10:                          + " select * from [Order Details];";
  11:      using (SqlCommand SqlCmd = new SqlCommand(strSQL, SqlCon))
  12:      {
  13:          if (SqlCon.State != ConnectionState.Open) SqlCon.Open();
  14:          SqlDataReader SqlReader = SqlCmd.ExecuteReader();
  15:          gvOrders.DataSource = SqlReader;
  16:          gvOrders.DataBind();
  17:         
  18:          //讀取下一個ResultSet
  19:          SqlReader.NextResult();
  20:          gvOrderDetails.DataSource = SqlReader;
  21:          gvOrderDetails.DataBind();
  22:          SqlReader.Close();
  23:      }
  24:  }


【結論】
使用這種方式進行批次查詢雖然方便,但切記必須只篩選您所會用到的欄位,避免使用SELECT * FROM TableName的方式來回傳所有欄位。
應避免一次傳回過多的結果集。




原始文章出自於此

2011年12月22日 星期四

用DATALENGTH找出VARCHAR欄位中含有中文字的資料列

SELECT * FROM TABLE_NAME
WHERE LEN(USERID) <> DATALENGTH(USERID)

==================================

CREATE TABLE #T
(
 [TEXT] TEXT,
 [NTEXT] NTEXT,
 [VARCHAR] VARCHAR(30)

)
GO
INSERT INTO #T VALUES('123abcㄅㄆㄇ机楞撒', '123abcㄅㄆㄇ机楞撒', '123abcㄅㄆㄇ机楞撒');
GO
SELECT
       --CAST ([TEXT] AS VARCHAR) AS 'TEXT(VARCHAR)',
       LEN(CAST ([TEXT] AS VARCHAR)) AS 'LEN_TEXT(VARCHAR)',
       DATALENGTH([TEXT]) AS 'DATALEN_TEXT',
     
       LEN(CAST([NTEXT] AS NVARCHAR)) AS 'LEN_NTEXT(NVARCHAR)',
       DATALENGTH([NTEXT]) AS 'DATALEN_NTEXT',
                    
       LEN([VARCHAR]) AS 'LEN_VARCHAR',
       DATALENGTH([VARCHAR]) AS 'DATALEN_VARCHAR'
     
FROM #T;
GO
DROP TABLE #T;
GO


原始文章出自於此



2011年11月30日 星期三

亂數產生5個數字字元進行UPDATE

此法不好
SELECT RIGHT(CONVERT(varchar ,Rand()),5) as RandomNumber

此法比較好
RIGHT(CONVERT(varchar,abs(cast(cast(newid() as binary(4)) as int)) + 30000000000),5)



原文出自於此

2011年11月27日 星期日

T-SQL 增強介紹

在這版中提供了一些新的T-SQL語法及物件,詳細資料可參考以下Link,這裡針對其中幾個比較感興趣的做介紹
http://technet.microsoft.com/en-us/library/cc645577(SQL.110).aspx


(1)分頁:在SQL2008,我們可能會利用row_number()來進行分頁查詢的設計,藉由row_number()的
自動編號,來計算本頁次要取出的資料,其編號是介在幾號~幾號之間,例如:我想要每10筆為一頁,
所以如果我現在要查詢第2頁,那麼資料就應該是編號為11~20的這10筆資料,因此我只要回傳這10筆
即可


(2)iif:這個字眼,如果有寫過VBA或Excel的人應該不陌生,我直接以一個原本是由case when的語法
改成iif


(3)EOMonth:取月份最後一天

(4)Concat:字串相加

(5)集合運算效能提升:詳細資料可參考
http://msdn.microsoft.com/zh-tw/library/ms189461(v=SQL.110).aspx




其他詳細資料內容請看這

2011年11月8日 星期二

如何利用T-SQL來做到類似Excel的樞紐分析表

假設我有三個資料表分別是Students、Subjects及Scores,用來存放學生資料、科目資料及考試成績資料(如下圖),若考試成績未達60分,則必須參加補考,考到及格為止。
image

因此我們可能以下列T-SQL來取得每個學生每一科的最高分數:
   1:  select t2.Name as StudentName,t3.Name as SubjectName
   2:              ,MAX(t1.Score) as MaxScore
   3:  from dbo.Scores t1
   4:  inner join dbo.Students t2 
   5:      on t1.StudentID = t2.StudentID
   6:  inner join dbo.Subjects t3
   7:      on t1.SubjectID = t3.SubjectID
   8:  group by t2.Name,t3.Name
   9:  order by t2.Name,t3.Name


執行結果如下:
image


若我們想把每個學生的每一科目變成是資料行,如同EXCEL的樞紐分析表一樣(如下圖),在SQL Server 2005以後的版本,可以利用Pivot關係運算子來完成。

image


完整程式碼如下:
   1:  select p1.StudentName as 姓名,p1.國文,p1.英文,p1.數學,p1.物理
   2:  from 
   3:  (
   4:      select t2.Name as StudentName,t3.Name as SubjectName,t1.Score
   5:      from dbo.Scores t1
   6:      inner join dbo.Students t2 
   7:          on t1.StudentID = t2.StudentID
   8:      inner join dbo.Subjects t3
   9:          on t1.SubjectID = t3.SubjectID
  10:  ) as s1
  11:  pivot 
  12:  (
  13:      MAX(s1.Score)
  14:      for s1.SubjectName
  15:      IN ([國文],[英文],[數學],[物理])
  16:  ) as p1    

執行結果如下:
image



原始文章出自於此



2011年8月1日 星期一

T-SQL 簡易語法手札

 //更新欄位值為指定查詢條件結果為相同主機不同資料庫之間的表格欄位資料,適用於複製相同主機不同資料庫裡面相同資料表之間的相同欄位資料的值。[2011-8-1]
UPDATE 
[MS_SQL_DB].[dbo].[ArticleData_Tb]
SET [Content_F] = (SELECT Temp_DB.dbo.ArticleData_Tb.Content_F FROM Temp_DB.dbo.ArticleData_Tb WHERE Temp_DB.dbo.ArticleData_Tb.NO_F = MS_SQL_DB.dbo.ArticleData_Tb.NO_F)


//更新欄位值為替代指定部份字串條件後的新資料的值。[2011-8-1]
UPDATE [MS_SQL_DB].[dbo].[BookDataLimit_Tb]
SET [RunJob_F] = REPLACE(RunJob_F, '瀏覽', 'View')
WHERE [RunJob_F] LIKE '%瀏覽%'






不斷更新的來源