星期二, 3月 23, 2021

[SQL] SQL Server 標準版本的 CPU 限制

要升級 SQL Server 2016 時發現到對於標準版 CPU 限制有嚴重誤解,觀念上一直以為標準版只能吃到 4 Core,查文件才發現是 4 Socket 或是 24 Core,兩條件最小值 為限制,4 Core 觀念不知道是哪來的,Orz

該圖為 SQL Server 版本的計算容量限制 內說明截圖

建立 VM 時預設是 1 Socket 1 Core


VM 設定:1 Socket 1 Core 設定

SQL Server 紀錄檔案內可以看見只能吃到 4 Core 的文字說明

CPU 滿載語法確認只吃到 4 Core

修正 VM CPU 設定值,從 1 Socket 1 Core 改為 1 Socket 2 Core


VM 設定:4 Socket 2 Core 設定

SQL Server 紀錄檔案內可以看見吃到 8 Core 的文字說明

CPU 滿載語法確認吃到 8 Core

星期一, 3月 22, 2021

[SQL] 移動使用者資料庫

根據該篇官方文章 - 移動使用者資料庫 的筆記,文章內說明
在 SQL Server 中,您可以在 ALTER DATABASE 陳述式的 FILENAME 子句中指定新的檔案位置,以便將使用者資料庫的資料、記錄和全文檢索目錄檔案移到新位置。 這種方法適用於在相同的 SQL Server執行個體內移動資料庫檔案。 若要將資料庫移到另一個 SQL Server 執行個體或移到另一個伺服器,請使用備份和還原或卸離和附加作業。
搬移使用者資料 4 個步驟
  1. 把 DB 設為離線
  2. 修改 DB 檔案位置,設定為新位置
  3. 把檔案搬移至新位置
  4. 讓 DB 上線
上述語法可以確認 DB logical_name 和檔案實體位置
SELECT 
  DB_NAME([database_id]) AS [database_name], 
  [state_desc] AS  OnlineStatus,
  [file_id],
  [type_desc] AS [file_type], 
  [name] AS [logical_name], 
  [physical_name]
FROM sys.[master_files]
WHERE [database_id] IN (DB_ID('DemoDBMove'))
ORDER BY [type], DB_NAME([database_id]);
[SQL] 移動使用者資料庫-1
-- Step1:設定 DB 離線
ALTER DATABASE DemoDBMove SET OFFLINE WITH ROLLBACK IMMEDIATE;

-- Step2:透過上述查詢語法找出 logical_name 並設定 DemoDBMove mdf 和 ldf 檔案位置至 D:\Temp 去
ALTER DATABASE DemoDBMove MODIFY FILE ( NAME = DemoDBMove, FILENAME = 'D:\Temp\DemoDBMove.mdf');
ALTER DATABASE DemoDBMove MODIFY FILE ( NAME = DemoDBMove_log, FILENAME = 'D:\Temp\DemoDBMove_log.ldf');

-- Step3:從原檔案位置搬移 DemoDBMove mdf 和 ldf 檔案至 D:\Temp 去

-- Step4:設定 DB 上線
ALTER DATABASE DemoDBMove SET ONLINE;
[SQL] 移動使用者資料庫-2

星期三, 3月 17, 2021

[EF] 移動 edmx 內的 model

實務會有需求是把 model 放在單一資料夾或 Project 內統一管理,該筆記是把 edmx 內的 Model tt 檔案移至另外的資料夾去

AdventureWorks edmx 已事先建立,且只拉近一個 Address,從下圖可以看見 edmx 內有兩個 tt 檔案,分別為 AdventureWorks.Context.tt 和 AdventureWorks.tt,目標是要把 AdventureWorks.tt 移到 EFModel 資料夾內

[EF] 移動 Edmx 內的 Model-1

在 EFModel 內新增 EF 6.x DbContext 產生器,並取為 AdventrueWorks.tt

[EF] 移動 Edmx 內的 Model-2

新增完成後會在 EF Model 內看見 AdventureWorks.Context.tt 和 AdventureWorks.tt 這兩個新的 tt 檔案,AdventureWorks.tt 為 Model 新存放處

[EF] 移動 Edmx 內的 Model-3

打開 EFModel 資料夾內的 AdventureWorks.tt 檔案,並修正 inputFile 為 @"..\DBContext\AdventureWorks.edmx";,讓 edmx 更新時會把 model 放在此處

[EF] 移動 Edmx 內的 Model-4

打開 DBContext 資料夾內的 AdventureWorks.Context.tt,並搜尋 using 關鍵字後,把 EFModel namespace 給加進去,如下圖

[EF] 移動 Edmx 內的 Model-5

儲存後就可以看見 EFModel 資料夾內的 AdventureWorks.tt 內產生 Address.cs,經過上述兩步驟就算是完成 AdventureWorks.tt 檔案搬移,最後刪除
  • DBContext 資料夾內的 AdventureWorks.tt (已移轉) 
  • EFModel 資料夾內的 AdventureWorks.Context.tt  (新增時自動產生,但沒有用到)
[EF] 移動 Edmx 內的 Model-6

在 edmx 內再把 AddressType 給加進來,就可以看見 EFModel 資料夾的 AdventureWorks.tt 下出現 AddressType.cs 檔案

[EF] 移動 Edmx 內的 Model-7

更換位置後,假如有需要變成 namespace 的話,tt 檔案都有 [自訂工具命名空間] 屬性可以設定調整

星期二, 3月 16, 2021

GodexRT730X-卡榫斷裂

使用者告知,標籤機碳帶回收不完整,只要大量列印後,就會有段碳帶在機器外,如下圖

Godex-RT730X 維修-1

檢測時把異常情況錄下來,發現回收時會有明顯的停頓,導致碳帶回收和出紙沒有同步


廠商帶回檢修後,發現卡榫下方斷裂

Godex-RT730X 維修-2

換上新品就恢復正常

Godex-RT730X 維修-3

星期一, 3月 15, 2021

GoTools

因為公司 Godex 標籤機異常,有經銷商來公司處理時,發現是透過 GoTools 這套官方軟體來進行重置標籤機設定,以往都是透過 GoLabel 軟體而已,操作看看有那些差異

GoTools 內有三種軟體,分別為 GoConfig、GoDoctor 和 GoLoader

GoTools-1

來處理人員是透過 GoDoctor 來重置標籤機設定

GoTools-2

在 GodexEZ1300Plus 異常排除 該篇筆記內的 GoLabel 版本,有紀錄搜尋標籤機功能,但是重新安裝 GoLabel V1.17 內已經沒有該畫面,取而代之的是另外一個搜尋功能,且只有搜尋的樣子,但在 GoTool 內的三套軟體都有下圖搜尋功能可以使用,比較貼近筆記內的截圖

GoTools-3

星期五, 3月 12, 2021

[SQL] DB 檢視權限

看討論提到公司內部有 [只看見特定 DB 的權限設計],腦海裡觀念是這作不到阿,趕快查資料並更新這錯誤觀念
-- 建立 DBViewDemo 使用者
CREATE LOGIN [DBViewDemo] WITH PASSWORD=N'P@ssW0rd'

-- 隱藏全部 DB
DENY VIEW ANY DATABASE TO [DBViewDemo]

-- 授予 DBViewDemo AdventureWorks2017 DB 存取權限,設定後會是 db_owner
ALTER AUTHORIZATION ON DATABASE::[AdventureWorks2017] TO [DBViewDemo]
設定後結果
[SQL] DB 檢視權限

星期六, 3月 06, 2021

[SQL] Foreign Key - Delete

之前在 Foreign Key 對應欄位建立索引,觀念上是因為對應欄位,通常也是 JOIN ON 條件欄位,建立有助於搜尋資料,日前找資料時發現,原來 Foreign Key 的存在,對於 DELETE 語法也會有影響

建立測試環境,因為目的是呈現 Foreign Key 存在對 DELETE 影響,所以沒有塞進任何資料
USE AdventureWorks2017
GO 

-- 建立 Master、Detail Table
DROP TABLE IF EXISTS tblMaster
DROP TABLE IF EXISTS tblDetail

CREATE TABLE tblMaster (MasterID int Primary Key)
CREATE TABLE tblDetail (DetailID int Primary Key, MasterID int)

-- 建立 Master、Detail 之間的 Foreign Key
ALTER TABLE [dbo].[tblDetail] WITH CHECK ADD CONSTRAINT [FK_tblDetail_tblMaster] FOREIGN KEY(MasterID)
REFERENCES [dbo].[tblMaster] (MasterID)

-- 建立 Detail 上,Foreign Key 對應欄位 Index
CREATE INDEX IX_tblDetail_MasterID ON tblDetail (MasterID)
CASE1:Foreign Key 和 IX_tblDetail_MasterID 同時存在,刪除 Master 單筆資料
DELETE FROM tblMaster WHERE MasterID = 1
從下方執行計畫可以觀察到,只刪除 Master Table 資料,有 Foreign Key 情況下,會利用 Index Seek 搜尋 Detail Table 內資料

[SQL] Foreign Key 上建立對應索引-1 CASE2:Foreign Key 存在、移除 IX_tblDetail_MasterID 情況,刪除 Master 單筆資料
-- 移除 IX_tblDetail_MasterID Index
DROP INDEX IX_tblDetail_MasterID ON tblDetail
DELETE FROM tblMaster WHERE MasterID = 2
從下方執行計畫可以觀察到,只刪除 Master Table 資料,有 Foreign Key 情況下,因為移除 Index,所以是利用 Index Scan 搜尋 Detail Table 內資料

[SQL] Foreign Key 上建立對應索引-2 CASE3:移除 Foreign Key 情況,刪除 Master 單筆資料
-- 移除 Foreign Key
ALTER TABLE dbo.tblDetail DROP CONSTRAINT FK_tblDetail_tblMaster
DELETE FROM tblMaster WHERE MasterID = 3
從下方執行計畫可以觀察到,只刪除 Master Table 資料,沒有 Foreign Key 情況下並不會對 Detail Table 進行任何搜尋

  [SQL] Foreign Key 上建立對應索引-3

 從上面三個 CASE 可以了解 Foreign Key 存在對於 DELETE 語法影響和建立對應欄位 Index 的必要性

星期五, 3月 05, 2021

[RV] 子報表

把該篇筆記 - [SSRS] 子報表 修正,用 ReportViewer 來呈現並紀錄使用方式。

ReportViewer 子報表必須透過 SubreportProcessing Event 來塞 DataSource 進子報表,本篇想記錄的重點
using Dapper;

namespace SubReport
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            reportViewer1.LocalReport.ReportEmbeddedResource = "SubReport.子報表.rdlc";
            List<RVMPurch> PurchList = GetRVMPurch();
            // 故意把報表內資料集名稱取的跟 Class 一樣
            reportViewer1.LocalReport.DataSources.Add(new ReportDataSource(nameof(RVMPurch), PurchList));
            reportViewer1.LocalReport.SubreportProcessing += LocalReport_SubreportProcessing;
            reportViewer1.RefreshReport();
        }

        private void LocalReport_SubreportProcessing(object sender, SubreportProcessingEventArgs e)
        {
            string PurNO = e.Parameters["PurNO"].Values[0]?.ToString();
            List<RVMPurchDetail> PurchDetailList = GetRVMPurchDetails(PurNO);
            // 故意把報表內資料集名稱取的跟 Class 一樣
            e.DataSources.Add(new ReportDataSource(nameof(RVMPurchDetail), PurchDetailList));
        }

        #region DB 存取相關
        private string ConnectionString = @"Data Source=.\SQL2017;Initial Catalog=AdventureWorks2017;Integrated Security=True;";

        private List<RVMPurch> GetRVMPurch()
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                string TSQL = @"
                        SELECT 
                          P.* , 
                          E.EmpName , 
                          S.SPLName , 
                          S.Contact , 
                          S.Tel , 
                          S.Fax
                        FROM Purch AS P
                          JOIN Employ AS E ON P.PurEmpNO = E.EmpNO
                          JOIN Supplier AS S ON P.SPLNO = S.SPLNO";

                return conn.Query<RVMPurch>(TSQL).ToList();
            }
        }

        private List<RVMPurchDetail> GetRVMPurchDetails(string purNO)
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                string TSQL = @"
                    SELECT * 
                    FROM PurchDetail 
                    WHERE PurNO = @PurNO";

                object para = new { PurNO = purNO };
                return conn.Query<RVMPurchDetail>(TSQL, para).ToList();
            }
        } 
        #endregion
    }
}

星期三, 3月 03, 2021

[RV] Subreport could not be shown

利用 ReportViewer 製作 Master-Detail 相關報表時,有用上子報表功能,但是子報表一直顯示
Error:Subreport could not be shown
完全看不出是哪裡出問題
從網路上整理該訊息可能異常為
  • 主報表沒有設定參數,所以沒有參數傳遞至子報表

  • 子報表內沒有對應主報表參數,無法接收參數

  • 主報表和子報表參數資料形態不一致

檢查才發現,只在主報表內設定參數,忘記在子報表也要設定參數,設定完成後子報表就可以正顯示,另外發現該情況 SubreportProcessing Event 並不會被觸發,一開始以為是子報表 DataSource 有問題才顯示該訊息

閱讀之前筆記-[SSRS] 子報表,也沒有意識到子報表參數沒有設定,花了不少時間找問題,Orz