瀏覽標籤:

SQL Server

[C#][MSSQL] 連線結束後 Temp Table 沒有自動釋放 !?

上次 [C#] SQL 資料庫 Connection Pool 連線池觀念釐清 有提到可以開啟 Connection Pool 來減少開啟連線的效能耗損,但最近發現有 Stored Procedure 執行後沒有手動 Drop Temp Table,而 .NET 又將連線丟回 Pool 裡面造成 Temp Table 沒有被正常釋放的問題,下面來測試看看是不是真的會有這種情況發生。 閱讀更多

       

[MSSQL] SQL Server 的一些眉眉角角 part.2

小知識

    1. 交易中資料表會持續鎖定至交易結束或是連線結束
    2. 最外層的交易 `ROLLBACK`,內層就算 `COMMIT` 依然會復原變更
    3. 巢狀交易過程中的資料表都會鎖定直到交易結束,外層交易 `COMMIT` 內層交易卻沒有 `COMMIT` 資料表會被鎖定不會釋放
    4. 交易前加上 `SET XACT_ABORT ON` 可防止過程中發生錯誤沒有 `ROLLBACK` 造成鎖表的問題

閱讀更多

       

[MSSQL] SQL Server 的一些眉眉角角 part.1

目前工作 Database 方面主要都在使用 SQL Server,寫了近兩年的 Stored Procedure 也遇到了許多的問題,在這裡簡單筆記一下。

  1. 暫存資料表小知識
    * `#` 或 `##` 建立的暫存資料表,可從 `tempdb.暫存資料表` 找到。
    * `#` 建立的暫存資料表只有該連線可以取用;`##` 則是全部連線均可使用。
    * 連線結束時皆會自動刪除,若程式中有 Connection Pool 來管理連線則不會立刻刪除。
    * 父層 Stored Procedure 建立的暫存資料表子層也可以使用;子層 Stored Procedure 建立的暫存資料表父層也可以使用
  2. 若開啟交易 (Transaction) 但無提交異動 (Commit) 會發生資料表鎖死 (Table Lock) 的問題,切記要提交異動 (Commit)。
  3. 使用主鍵來 `UPDATE` 為資料鎖 (Row Lock),若使用其他條件則有可能會升級成資料頁鎖(Page Lock) 或資料表鎖 (Table Lock)。
  4. 交易 (Transaction) 具有復原機制 (RollBack),但實際上資料表中的資料已經被異動且鎖定的關係所以無法取得,可利用 `WITH(NOLOCK)` 來取得被鎖定的髒資料。
  5. 未開啟交易時使用 `CURSOR` 或 `UPDATE FROM` 若超過五千筆時可能會造成鎖定與死結,可使用 `ROW_NUMBER()` 排序資料塞入暫存資料表並使用 `WHILE` 來一筆一筆更新資料避開鎖定,速度雖慢但能減少鎖死。
    SET NOCOUNT ON
    
    DECLARE
        @RowNum         INT,
        @RowCount       INT,
        @Temp_Id        INT
    
    SELECT
        ROW_NUMBER() OVER(ORDER BY [Id]) AS RowNum,
        [Id],
        [Name]
    INTO
        #Temp
    FROM
        [exfast].[dbo].[TableA] WITH(NOLOCK)
    
    SELECT
        @RowNum = 1,
        @RowCount = (SELECT SUM(1) FROM #Temp)
    
    WHILE(@RowNum <= @RowCount)
    BEGIN
    
        SELECT
            @Temp_Id = [Id]
        FROM
            #Temp
        WHERE
            RowNum = @RowNum
    
        UPDATE
            [exfast].[dbo].[TableA]
        SET
            [Name] = 'dddd'
        WHERE
            [Id] = @Temp_Id
    
        SET @RowNum = @RowNum + 1
    
    END
    
    DROP TABLE #Temp
    
  6. 高負載情況下使用 `UPDATE OUTPUT` 的方法來取得資料更新前後的狀態,可減少 `SELECT` 次數提高效率。
    DECLARE  @TempA  TABLE
    (
        [INSERTED_Id]       INT,
        [INSERTED_Name]     NVARCHAR(32),
        [DELETED_Id]        INT,
        [DELETED_Name]      NVARCHAR(32)
    )
    
    UPDATE
        [exfast.Helper].[dbo].[TableA]
    SET
        [Name] = 'qqqq'
    OUTPUT
        INSERTED.[Id],
        INSERTED.[Name],
        DELETED.[Id],
        DELETED.[Name]
    INTO
        @TempA
    
    SELECT * FROM @TempA
  7. 高負載情況下可能會將隔離層級拉高到 Serializable,這時使用交易會發生相同資料表 `SELECT` `UPDATE` 中的 Shared Lock 與 Exclusive Lock 撞車造成 DeadLock,可在 `SELECT` 加上 `WITH(UPDLOCK)` 來減少此問題。
    -- 故意指定隔離層級模擬撞車的情況
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    
    BEGIN TRAN
    
    SELECT * FROM [exfast.Helper].[dbo].[TableA]
    
    WAITFOR DELAY '00:00:10'
    
    UPDATE
        [exfast.Helper].[dbo].[TableA]
    SET
        [Name] = 'cccc'
    WHERE
        [Id] = 2
        
    ROLLBACK
       

[Docker][Linux] SQL Server 安裝筆記

環境:Window 7

  1. 安裝 Docker Toolbox
  2. 新增 Volume
docker volume create vol-mssql

 

  1. 建立容器
docker run \
--restart=always \
--name mssql \
--mount "source=vol-mssql,target=/var/opt/mssql" \
-e "ACCEPT_EULA=Y" \
-e "SA_PASSWORD=1OCHWiY9O#RF" \
-e "MSSQL_PID=Express" \
-e "MSSQL_COLLATION=Chinese_Taiwan_Stroke_CI_AS" \
-p 1433:1433 \
-d microsoft/mssql-server-linux:latest

 

  1. 更新時區
docker exec -ti mssql bash
apt-get update
apt-get install tzdata -y
dpkg-reconfigure tzdata

 

參考資料:

  1. Linux Docker 運行 MSSQL
  2. 快速入門: 使用 Docker 執行 SQL Server 2017 容器映像
  3. 在Linux上使用环境变量配置SQL Server设置
       

[MSSQL] 當自動識別欄位需要Insert資料時應該怎麼辦 ?

今天在手動將MySQL資料匯入MSSQL時遇到了這個問題,但又不想將自動識別欄位取消掉,於是乎找了一下資料來解決 …

 

語法:

SET IDENTITY_INSERT TABLE_NAME OFF;
SET IDENTITY_INSERT TABLE_NAME ON;

 

範例:

SET IDENTITY_INSERT [dbo].[Demo] ON;

INSERT INTO [dbo].[Demo] ([ID], [Name]) VALUES (N'1', N'王小名');

INSERT INTO [dbo].[Demo] ([ID], [Name]) VALUES (N'2', N'王大名');

SET IDENTITY_INSERT [dbo].[Demo] OFF;

 

 

參考:

  1. 在程式開發時使用SET IDENTITY_INSERT似乎無效?
  2. SQL錯誤訊息:當IDENTITY_INSERT 設為OFF 時,無法將外顯
       

[MSSQL] 使用 T-SQL 實作分頁

很多表格會遇上資料有上萬筆資料或者上千萬時的大數據,這時如果還是把所有資料撈出來在分頁的話,會造成使用者頁面讀取時間過久,更會有伺服器壓力倍增的問題,這裡提供一個SQL解決方案。

SQL如下:

DECLARE @PageNum AS BIGINT;
DECLARE @PageSize AS BIGINT;
DECLARE @PageCount AS BIGINT;
SET @PageNum = 3;
SET @PageSize = 10;
SET @PageCount = (	SELECT	COUNT(1)
					FROM	dbo.TBase_Product
					WHERE	Product_State != 9) / @PageSize;

IF @PageNum < 1	SET @PageNum = 1;

WITH Temp AS
(
	SELECT	*,
			ROW_NUMBER() OVER(ORDER BY Product_ID) AS RowNum
	FROM dbo.TBase_Product
)

SELECT	RowNum, @PageCount AS PageCount
FROM	Temp
WHERE	RowNum 
		BETWEEN ((@PageNum - 1) * @PageSize + 1) 
			AND (@PageNum * @PageSize)
ORDER BY Product_ID;

執行結果:

2016-09-03 01_01_10-SQLQuery9.sql - exfast.me,6000.iPCE_Coding (shuangrain (143))_ - Microsoft SQL S

 

 

參考:

  1. How to return a page of results from SQL?
  2. Select Count(*) / Count(1) / Count(欄位名) 的差異
       

[MSSQL] SQL Server Management Studio 連線非預設 1433 port 埠號

參考:SQL Server 透過 TCP/IP 遠端連線時如何使用非 1433 埠號

 

未命名

自從把SQL Server放到公用網路上的時候,就常常被人暴力破解Try我的密碼,雖然不至於被猜到,但是看了總是不太開心,於是乎就把預設的Port修改掉了,卻發生使用SQL Server Management Studio無法連線的問題,之前用MySQL時格式不外乎就是在後面加上:port但轉來MSSQL卻發生無法連線的問題…

 

爬了一下文才發現,使用ip,port(127.0.0.1,4321)這種格式就可以正常連線囉!
2016-08-20 18_18_00-連接到伺服器

       

[MSSQL] SQL Server Management Studio 連線工具

來源:使用 SQL Server Management Studio 連接到 SQL Database 並執行範例 T-SQL 查詢

 

SQL Server Management Studio (SSMS) 是一個整合式環境,您可以加以利用來存取、設定、管理及開發 SQL Server 的所有元件。 SSMS 利用許多豐富的指令碼編輯器來合併一群非常廣泛的圖形工具,使所有技術層級的開發人員及管理員都能夠存取。 此版除了提升與舊版 SQL Server 之間的相容性之外,也改進了獨立 Web 安裝程式,以及 SSMS 中,當有新版本可用時的快顯通知。

 

下載 SQL Server Management Studio (SSMS)

 

筆記一下…

2016-07-31 02_52_18-Microsoft SQL Server Management Studio

       
  • 1
  • 2