星期日, 5月 26, 2019
[VSTS] Force push 查詢
[VSTS] Force push 權限控制 該篇延續,想說是否可以查到有人使用 git push -f 指令,在 Azure DevOps 內發現,原來使用 Force push 該 push 會特別標記起來
星期四, 5月 23, 2019
[VSTS] Force push 權限控制
同事所屬專案目前算是一人專案,因為使用 git push -f 時被擋下來,希望能加入 Project Administrator,使其有權限可以操作,確認後才發現,即使是 Project Administrator 也必須明確指定才能使用
原來 Azure DevOps 可以防止 -f 參數的使用,趁機了解到底有哪些細節是可以進行設定
原來 Azure DevOps 可以防止 -f 參數的使用,趁機了解到底有哪些細節是可以進行設定
星期一, 5月 20, 2019
[SQL] 標準報表-結構描述變更紀錄
參加研討會時,老師說明透過 [結構描述變更紀錄報表],在沒有事先建立 DDL Trigger、開啟 Audit 的情況下,抓到刪除重建 Table 的兇手,才注意到有這張標準報表,原以為是透過 Extend Event 來產生的,實際測試時發現是抓取 Default SQL Trace 內的資料
- 利用 T-SQL 語法檢查 SQL Server 是否有 DDL 操作,並發信通知 DBA
CREATE PROCEDURE uspDDLCheck
AS
BEGIN
DECLARE @curr_tracefilename varchar(500) ;
DECLARE @base_tracefilename varchar(500) ;
DECLARE @indx int ;
SELECT @curr_tracefilename = [path] FROM sys.traces WHERE is_default = 1 ;
SET @curr_tracefilename = REVERSE(@curr_tracefilename);
SELECT @indx = PATINDEX('%\%', @curr_tracefilename) ;
SET @curr_tracefilename = REVERSE(@curr_tracefilename) ;
SET @base_tracefilename = LEFT(@curr_tracefilename,LEN(@curr_tracefilename) - @indx) + '\log.trc' ;
IF EXISTS
(
SELECT 1
FROM fn_trace_gettable( @base_tracefilename, default )
WHERE DatabaseID = db_id()
AND EventClass in (46,47,164)
-- 46 為 CREATE
-- 47 為 DROP
-- 164 為 ALTER
AND EventSubclass = 0
AND ObjectType NOT IN (17747,21587)
-- 17747 為 Security Event
-- 21587 為統計資訊
AND ObjectID > 100
-- ObjectID 100 以下為系統物件
AND DatabaseName NOT IN ('tempdb')
-- 可能會在 TempDB 內操作 Temp Table,不列入追蹤
AND StartTime > DATEADD(HH, -24, GETDATE())
-- 判斷昨天有沒有發生
AND CHARINDEX('SQLAgent' , ApplicationName) = 0
-- 排程工作,EX:維護索引,不列入追蹤
)
BEGIN
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'Database Mail Profile' ,
@recipients='DBA@gmail.com' ,
@subject = 'DDL Alert',
@body = 'DDL is triggered' ,
@body_format = 'TEXT'
END
END
- 延伸閱讀
- [SQL] 標準報表 - 磁碟使用量
- 參考資料
- ObjectType 追蹤事件資料行
- The default trace in SQL Server – the power of performance and security auditing - 有整理好的 ObjectType 可以使用
星期六, 5月 11, 2019
[VFP] SPT 日期轉換
傳進 SPT 的 VFP Date 參數 0108/05/11 都會習慣轉為 2019-05-11,某天看到自己的 Code 發現,怎麼把 VFP Date 直接傳入 SPT 內,該功能已經運行一段時間,有問題的話,使用者應該早就反應才對,利用 SQL Profile 確認後,才發現原來 VFP Date 傳進 SPT 後,會自動轉換,原來一直以來都多一道處理步驟,Orz
SQL Profile 側錄的參數
SQL Profile 側錄的參數
- @P1 參數值:0108/03/01 => '2019-03-01'
- @P2 參數值:0108/04/30 => '2019-04-30'
星期五, 5月 10, 2019
[C#] ExpandoObject
同事介紹 ExpandoObject 認識,就 MSDN 文章 - ExpandoObject Class,簡易記錄一下
MSDN 說明
MSDN 說明
The ExpandoObject class enables you to add and delete members of its instances at run time and also to set and get values of these members. This class supports dynamic binding, which enables you to use standard syntax like sampleObject.sampleMember instead of more complex syntax like sampleObject.GetAttribute("sampleMember")C# Code
using System.Dynamic;
using System.ComponentModel;
namespace Basic
{
class Program
{
static void Main(string[] args)
{
dynamic sampleObject = new ExpandoObject();
// 動態新增 Property
sampleObject.Property = "Dynamic Property";
Console.WriteLine("----- 動態新增 Property -----");
Console.WriteLine($"Type:{sampleObject.Property.GetType()} - Property Value:{sampleObject.Property}");
// 動態新增 Method
sampleObject.number = 10;
sampleObject.Increment = (Action)(() => { sampleObject.number++; });
Console.WriteLine("----- 動態新增 Method -----");
Console.WriteLine($"原值:{sampleObject.number}");
sampleObject.Increment();
Console.WriteLine($"增值:{sampleObject.number}");
// 動態新增 Event
sampleObject.sampleEvent = null;
Console.WriteLine("----- 動態新增 Event -----");
sampleObject.sampleEvent += new Action<object, EventArgs>((sender, e) =>
{
Console.WriteLine($"SampleHandler for {sender} event");
});
sampleObject.sampleEvent(sampleObject, new EventArgs());
// 參數傳遞
dynamic employee, manager;
employee = new ExpandoObject();
employee.Name = "John Smith";
employee.Age = 33;
manager = new ExpandoObject();
manager.Name = "Allison Brown";
manager.Age = 42;
manager.TeamSize = 10;
WritePerson(manager);
WritePerson(employee);
// 移除 Name Property
((IDictionary<String, Object>)employee).Remove("Name");
Console.WriteLine("----- 移除 Name Property -----");
foreach (var property in (IDictionary<String, Object>)employee)
{
Console.WriteLine($"{property.Key} : {property.Value}");
}
// PropertyChanged Event
((INotifyPropertyChanged)employee).PropertyChanged += ((sender, e) =>
{
Console.WriteLine($"{e.PropertyName} has changed.");
});
Console.WriteLine("----- PropertyChanged Event -----");
employee.Name = "John Smith";
}
static void WritePerson(dynamic person)
{
try
{
Console.WriteLine($"{person.Name} is {person.Age} years old in Team {person.TeamSize}.");
}
catch (Exception ex)
{
Console.WriteLine($"{person.Name}:{ex.Message}");
}
}
}
}
星期六, 5月 04, 2019
[SQL] Profile 整合 Trace 與 Performace Count
事先已經有錄製好的超過 1 sec 的 Trace 和 Performace Count 資料,紀錄如何透過 Profile 整合應用
在 Profile 內,開啟 Trace 檔案
在 Profile 內,匯入 Performace Count 並選擇要顯示的 Count 選項
兩者整合後畫面,由上而下分為 4 大部分
Trace 語法和 Performace Count 線圖會根據時間連動,所以錄製 Trace 時,一定要有 StartTime 和 EndTime 資訊,而實務上大多是去點選線圖峰值,當點選峰值時,第四部份的 TSQL 變成紅色時,表示正在執行的 TSQL 語法,設法調校改善就對啦
在 Profile 內,開啟 Trace 檔案
在 Profile 內,匯入 Performace Count 並選擇要顯示的 Count 選項
兩者整合後畫面,由上而下分為 4 大部分
- Trace 語法
- Performace Count 線圖
- Count 選項 - 只選擇 Avg. Disk Queue Length,避免太混亂
- TSQL 語法
Trace 語法和 Performace Count 線圖會根據時間連動,所以錄製 Trace 時,一定要有 StartTime 和 EndTime 資訊,而實務上大多是去點選線圖峰值,當點選峰值時,第四部份的 TSQL 變成紅色時,表示正在執行的 TSQL 語法,設法調校改善就對啦