2016年3月29日 星期二

SQL 取多筆欄位合併的寫法

如需要使用到一對多的資料查詢字串,例如一個學生一學期上過那些課,將課程串成一個字串該如何寫。
請教Google大神找到一個叫做For XML Path的作法
  1. 資料表有ClassTable、SubjectNameTable、StudentTable
  2. ClassTable
    • Year-學年
    • SubjectID-科目代碼
    • StudentNumber -學號
  3. SubjectNameTable
    • SubjectID-科目代碼
    • SubjectName-科目名稱
  4. StudentTable
    • StudentNumber-學號
    • StudentName-姓名

select StudentName, 
    STUFF((select ',' + RTRIM(SubjectName) from ClassTable
        inner join SubjectNameTable 
                           on ClassTable.SubjectID = SubjectNameTable .SubjectID 
        where ClassTable.Year=104 
            and ClassTable.StudentNumber = StudentTable.StudentNumber
        for xml path('')),1,1,'') as SubjectName from StudentTable
where StudentNumber='001'

2016年3月23日 星期三

建立SignalR網站

  1. 開啟VS2013,建立Web專案,選取MVC,變更驗證選不驗證。
  2. 開啟套件管理員執行Install-package Microsoft AspNet.SignalR  。
    • 注意安裝完的readme.txt,會說明修改的部分 
    • Scripts多出jquery.signalR-2.2.0.js,參考多出 Microsoft.AspNet.SignalR.Code及 Microsoft.AspNet.SignalR.SystemWeb 
  3. 新增一個資料夾名為Hubs
    • 在此資料夾新增一個項目選取SignalR Hub類別,取名為ChatHub.cs
    • 建完後將程式碼改成如下
  4. 新增一個Startup.cs的類別檔
    • 程式碼如下
  5. 開啟Controllers/HomeController.cs
    • 增加以下程式碼
  6. 在Chat上按右鍵,新增一個View
    • 程式碼如下
  7. 執行起來,用兩個瀏覽器開啟,一開始會先輸入使用者,接著看兩邊的訊息是否會互通。

參考來源: Getting Started with SignalR 2 and MVC 5

2016年3月21日 星期一

EntityFramework無法匯入View作為EDMX的實體

今天因需求需要匯入View到EF裡,發生匯進來後找不到實體,開啟EDMX的XML描述出現此訊息,
<!--產生期間發現錯誤:
警告 6002: 資料表/檢視 'Sal.dbo.test' 未定義主索引鍵。已推斷此索引鍵,並將定義建立成唯讀的資料表/檢視。-->

在這我們不去修改EDMX的XML檔,避免日後在更新時又會回復到原樣,我們還是採取在資料庫增加Key值的方式,看了保哥的文章才發現原來在view裡可以設定讓EF判斷此欄位為Key值得方式,在欄位上判斷ISNULL的方式:

SELECT          ISNULL(B02IDNO, '') AS B02IDNO, B02NAME, B02POINT, B02TPOINT
FROM              dbo.CPATemp

參考來源:解決 SQL Server 檢視表 (Views) 無法匯入 EDMX 的問題

SQLServer 連結伺服器別名

因專案上的需要要連結到其他SQLServer做查詢,因為對方沒有開具名管道所以我就使用IP做連結,剛好也是SQLSERVER所以在伺服器類型就選SQL SERVER,
因為原本要在View上利用此伺服器連結做資料查詢,但發現用IP的方式存檔SQLServer會自動把中誇號濾掉導致語法問題,所以只能用具名管道或是別名的方式設定此連結,因為對方沒開具名管道所以只能設定別名,設定方式如下:
  1. 連結的伺服器:設定想要連結的名稱 ,也就是別名
  2. 伺服器類型:選其他來源
  3. 提供者:SQL Server Native Client 10.0
  4. 產品名稱:可自行定義
  5. 資料來源:輸入IP
  6. 安全性頁籤則造常輸入

完成後側是看是否可正常連線。

2016年3月18日 星期五

SQL DBCC 陳述式

  1. 從計畫快取移除所有元素;指定計畫控制代碼或 SQL 控制代碼,從計畫快取移除特定的計畫;或是移除與指定的資源集區相關聯的所有快取項目。

  2. DBCC FREEPROCCACHE 
  3. 排清散發查詢對 Microsoft SQL Server 執行個體所用的散發查詢連接快取。

  4. DBCC FREESESSIONCACHE
  5. 釋出所有快取中所有未使用的快取項目。 SQL Server Database Engine 會主動在背景清除未使用的快取項目,讓記憶體存放目前的項目。 不過,您可以使用這個命令,以手動方式從所有快取或是指定的資源管理員集區快取中移除未使用的項目。

  6. DBCC FREESYSTEMCACHE('All')
  7. 從緩衝集區中移除所有的清除緩衝區。

  8. DBCC DROPCLEANBUFFERS
  9. 重組指定資料表或檢視的索引。

  10. DBCC INDEXDEFRAG(DBName,'TableName')
  11. 顯示指定資料表或檢視之資料與索引的片段資訊。

  12. DBCC SHOWCONTIG(TableName)
  13. 報告和更正目錄檢視中不準確的頁面和資料列計數。 這些不準確可能會使 sp_spaceused 系統預存程序傳回不正確的空間使用方式報表。

  14. DBCC UPDATEUSAGE(DBName)
參考資料 MSDN

SQL SERVER PARTITION TABLE 分割Table

  1. 因成績資料的Table過於龐大,效能開始低落,想實作Partition Table看效能是否可改善。

  2. 只有在SQL SERVER Enterprise、Developer 和 Evaluation 版本以上才有支援Partition Table。

  3. 建立邏輯檔案群組及實體檔案位置。

  4. USE PartitionA 
    --建立FileGroup
    ALTER DATABASE [PartitionA] ADD FILEGROUP [PartitionTo90];
    ALTER DATABASE [PartitionA] ADD FILEGROUP [PartitionTo95];
    ALTER DATABASE [PartitionA] ADD FILEGROUP [PartitionTo100];
    
  5. 建立實體檔案位置。

  6. USE PartitionA 
    --
    DECLARE @PATH NVARCHAR(128);
    DECLARE @SQL VARCHAR(1000);
    --
    SELECT @PATH=physical_name FROM sys.database_files WHERE file_id = 1
    --
    --建立實體檔案對應
    SET @SQL = 'ALTER DATABASE [PartitionA] ADD FILE ( 
    NAME=[PartitionTo90], 
    FILENAME="' + @PATH + 'PartitionTo90.ndf", 
    SIZE=100MB ) TO FILEGROUP[PartitionTo90]';
    EXEC(@SQL)
    SET @SQL = 'ALTER DATABASE [PartitionA] ADD FILE ( 
    NAME=[PartitionTo95], 
    FILENAME="' + @PATH + 'PartitionTo95.ndf", 
    SIZE=100MB ) TO FILEGROUP[PartitionTo95]';
    EXEC(@SQL)
    SET @SQL = 'ALTER DATABASE [PartitionA] ADD FILE ( 
    NAME=[PartitionTo100], 
    FILENAME="' + @PATH + 'PartitionTo100.ndf", 
    SIZE=100MB ) TO FILEGROUP[PartitionTo100]';
    EXEC(@SQL)
    
  7. 以年度的範圍建立Partition Function,在這建立90年以前、91~95、96~,另外也可使用日期來做區隔, 詳細說明可參考Create Partition Function

  8. USE PartitionA 
    CREATE PARTITION FUNCTION PartitionTest(INT) AS RANGE RIGHT FOR 
    VALUES(90, 95);
    GO
    
  9. 建立Partition Scheme,根據Partition Function的值放到對應的檔案群組, 詳細說明可參考Create Partition Scheme

  10. USE PartitionA 
    CREATE PARTITION SCHEME PartitionTest AS PARTITION PartitionTest TO 
    (
     [PartitionTestTo90],
     [PartitionTestTo95],
     [PartitionTestTo100]
    )
    GO
    
  11. 建立一個檢查用的Function,此方法是可以依據切割的設定查看資料是否寫在正確的位置上。

  12. CREATE FUNCTION PartitionTestInfo( @tablename sysname ) returns table as return
    SELECT OBJECT_NAME(p.object_id) as TableName,
    p.partition_number as PartitionNumber,prv_left.value as LowerBoundary,
    prv_right.value as  UpperBoundary,ps.name as PartitionScheme,
    pf.name as PartitionFunction,fg.name as FileGroupName,
    CAST(p.used_page_count * 8.0 / 1024 AS NUMERIC(18,2)) AS UsedPages_MB
    FROM  sys.dm_db_partition_stats p
    INNER JOIN sys.indexes i ON i.object_id = p.object_id AND i.index_id = p.index_id
    INNER JOIN sys.partition_schemes ps ON ps.data_space_id = i.data_space_id
    INNER JOIN sys.partition_functions pf ON ps.function_id = pf.function_id
    INNER JOIN sys.destination_data_spaces dds ON 
        dds.partition_scheme_id = ps.data_space_id AND 
        dds.destination_id = p.partition_number
    INNER JOIN sys.filegroups fg ON fg.data_space_id = dds.data_space_id
    LEFT  JOIN sys.partition_range_values prv_right ON 
        prv_right.function_id = ps.function_id AND 
        prv_right.boundary_id = p.partition_number
    LEFT  join sys.partition_range_values prv_left  ON 
        prv_left.function_id = ps.function_id AND 
        prv_left.boundary_id = p.partition_number - 1
    WHERE p.object_id = OBJECT_ID(@tablename) AND p.index_id < 2
    GO
    
  13. 建立一個測試Table連結到Partition,將Table建立在PartitionTest的Partition Scheme上。

  14. CREATE TABLE [dbo].[test](
     [year] [int] NOT NULL,
     [student] [nchar](6) NOT NULL,
     [score] [decimal](7, 4) NULL,
    CONSTRAINT [PK_test] PRIMARY KEY CLUSTERED 
     (
      [year] ASC,
      [student] ASC
     )) ON PartitionTest([year])
    GO
    
  15. 新增一些測試資料,看是否有正確寫在對的地方,利用PartitionTestInfo查看狀況。

  16. SELECT * FROM PartitionAF71Info('dbo.test')
    
  17. 日後要新增新的Partition,一樣要增加FileGroup、實體檔案位置,調整Partition Function及Partition Scheme的區間

  18. --建立出新的Partition
    DECLARE @PATH NVARCHAR(128);
    DECLARE @SQL VARCHAR(1000);
    --
    SELECT @PATH=physical_name FROM sys.database_files WHERE file_id = 1
    --
    --產生下一個5年的群組
    ALTER DATABASE [PartitionA ] ADD FILEGROUP [PartitionTo105];
    --產生下一個5年的實體資料檔案
    SET @SQL = 'ALTER DATABASE [PartitionA ] ADD FILE ( NAME=[PartitionTo105], FILENAME="' + @PATH + 'PartitionTo105.ndf", SIZE=100MB ) TO FILEGROUP[PartitionTo105]';
    EXEC(@SQL)
    --變更Partition Scheme 指定新的資料群組
    ALTER PARTITION SCHEME [PartitionTest] NEXT USED [PartitionTo105]
    --變更Partition Function 指定新的Range
    ALTER PARTITION FUNCTION [PartitionTest]() SPLIT RANGE (100)
    
  19. 移轉資料,讓資料群組可刪除,建立一個Table跟原本的一樣,利用同樣的倘案群組,假設要移轉第一個區段。

  20. CREATE TABLE [dbo].[MOCK_test](
     [year] [int] NOT NULL,
     [student] [nchar](6) NOT NULL,
     [score] [decimal](7, 4) NULL,
    CONSTRAINT [PK_test] PRIMARY KEY CLUSTERED 
     (
      [year] ASC,
      [student] ASC
     )) ON PartitionTo90([year])
    GO
    
  21. 資料群組搬移出來後,要刪除資料群組,必須先刪除資料檔案才可刪除檔案群組。

  22. ALTER PARTITION FUNCTION PartitionTest() MERGE RANGE (90)
    SELECT * FROM PartitionAF71Info('dbo.test')
    USE [master]
    GO
    ALTER DATABASE [PartitionA ] REMOVE FILE [PartitionTo90]
    ALTER DATABASE [PartitionA ] REMOVE FILEGROUP [PartitionTo90]
    
參考資料 Partition Table 的實作筆記