透過 T-SQL 發送訂閱報表

use reportserver
go
declare @eventData uniqueidentifier
select @EventData=[EventData] from [dbo].[Subscriptions] s
join [dbo].[ReportSchedule] r on s.SubscriptionID=r.SubscriptionID
join [dbo].[Schedule] c on r.ScheduleID=c.ScheduleID
where s.Description=N'<建立訂閱時的描述>’
exec [ReportServer].dbo.AddEvent @EventType=’TimedSubscription’, @EventData=@eventData

image

Where 要填的內容就是上述的描述欄位

透過設定報表變數改變單雙列的背景顏色

建立報表變數 LineTotalNo 後

image

在報表增加函數

Public Function SetNo(val as Microsoft.ReportingServices.ReportProcessing.OnDemandReportObjectModel.Variable)  As Integer
    val.Value = val.Value + 1
    Return val.Value
End Function

Public Function GetNo(val as Microsoft.ReportingServices.ReportProcessing.OnDemandReportObjectModel.Variable)  As Integer
    Return val.Value
End Function

一個格子設定變數值,其他的格子取值就可以設定背景顏色單雙列不同

image
簡單報表範例:

https://onedrive.live.com/?cid=BF14192BD27975CB&id=bf14192bd27975cb%212277

比較 Cursor 的執行狀況

Ellie 和 Abby 提了一個有趣的問題,因為 Oracle 對 SQL Server 的存取會透過 Cursor,而針對 table 與 view 的 cursor 查詢,是否有效能差異?

簡單實驗如下:

use tempdb
create table tb(c1 int identity primary key,c2 varchar(100) default(‘Hello’),c3 datetime2(0) default(getdate()))
insert tb default values
go
insert tb(c2) select c2 from tb
go 20

create view vw
as
select top(10000) * from tb order by c1
go

declare @p1 int,@p2 int,@p5 int=1,@p6 int=1,@p7 int=1000000
exec sp_cursorprepexec @p1 output,@p2 output,NULL,N’select * from tb’, @p5 output,@p6 output,@p7 output
select @p1,@p2,@p5,@p6,@p7
set statistics io on
set statistics time on
exec sp_cursorfetch @p2,2,1,100
set statistics io off
set statistics time off

–觀察 cursor
declare @cur cursor
exec sp_cursor_list @cur output,3 –local 和 global
fetch @cur
/*
model:smallint  
1 = 不區分 (或靜態) 
2 = 索引鍵集 
3 = 動態 
4 = 向前快轉
*/
DEALLOCATE @cur

go

declare @p1 int,@p2 int,@p5 int=1,@p6 int=1,@p7 int=1000000
exec sp_cursorprepexec @p1 output,@p2 output,NULL,N’select * from vw’, @p5 output,@p6 output,@p7 output
select @p1,@p2,@p5,@p6,@p7
set statistics io on
set statistics time on
exec sp_cursorfetch @p2,2,1,100
set statistics io off
set statistics time off
–觀察 cursor
declare @cur cursor
exec sp_cursor_list @cur output,3 –local 和 global
fetch @cur
/*
model:smallint  
1 = 不區分 (或靜態) 
2 = 索引鍵集 
3 = 動態 
4 = 向前快轉
*/
DEALLOCATE @cur

就我實驗的結果,兩者雖然開的 Cursor Type 相同,都是 Keyset:

clip_image001

但 Keyset type 的 Cursor 在跑的時候,會參照開 Cursor 時的定義,所以會有效能的差異

clip_image002

換句話說,View 要寫得有效率才好,畢竟 View 有可能有欄位計算定義,而不僅是查詢資料表欄位,所以執行計畫需要照 View 來做。但 Order by 一定不是一個有效的語法…

若不是整個資料表都要轉到 Oracle,我想透過 View 是比較好,直接取 table 有可能全資料表都過去 Oracle 了,但寫 View 的語法要小心…

SQL Server 2016 原生編譯預存程序終於較為好用了

SQL Server 2016 版線上說明表列對原生編譯預存程序的支援

https://msdn.microsoft.com/zh-tw/library/dn452283(v=sql.130).aspx

缺掉粗體字的這幾項,SQL Server 2014 的原生預存程序能用的情境真少…

Windows Server Technical Preview 2(Windows 2016) 啟動 UI

http://sqlha.com/2015/05/05/need-a-user-interface-for-windows-server-technical-preview-2-its-not-on-by-default/

將簡單的 SSIS 2014 封裝轉成 2012 版本

有 30 來個相同的封裝,僅是內含執行封裝工作呼叫其他的封裝,但用的是 VS2013/BIDS 2014 開發的,但實際的 SQL Server 卻是 2012,所以簡單寫段 PowerShell 取代

$source=’C:\temp\ssis\2014\Integration Services 專案1\’
$files=dir ($source + ‘*.dtsx’)
$dest=Join-Path $source ‘temp\’
foreach($file in $files)
{
    (((((Get-Content $file.FullName) `
    -replace "Microsoft.Package", "SSIS.Package.3") `
    -replace "12.0.2456.0","11.0.5058.0") `
    -replace ‘DTS:VersionBuild="2"’,’DTS:VersionBuild="1"’) `
    -replace ‘DTS:Name="PackageFormatVersion">8</DTS:Property>’,’DTS:Name="PackageFormatVersion">6</DTS:Property>’ `
    -replace ‘Microsoft.ExecutePackageTask’,’SSIS.ExecutePackageTask.3′) `
    | Out-File (join-path $dest $file.Name) -encoding utf8
}

若封裝複雜,或是 2012(Attribute centric)換 2008 R2(Element centric)就完全不可能這麼做了,升級或選用封裝開發版本務必小心

加任意 bytes 數量的亂數值

use tempdb
go
CREATE VIEW rndView
AS
SELECT RAND() rndResult
GO

create function RandBytes
(
    @ByteLength int
)
returns varbinary(max)
as
begin
    declare @ret varbinary(max)=0x,@i int=0,@rndValue tinyint
    while @i<@ByteLength
    begin
        select @rndValue = convert(tinyint,rndResult*256)
        from rndView
        set @ret+=convert(binary(1),@rndValue)
        set @i+=1
    end
    return @ret
end
GO

create table #t(c1 nvarchar(10))
insert #t values(N’中文’),(N’測試一下’)

select dbo.RandBytes(10)+convert(varbinary(max),c1),
substring(dbo.RandBytes(10)+convert(varbinary(max),c1),11,datalength(convert(varbinary(max),c1))),
convert(nvarchar(max),substring(dbo.RandBytes(10)+convert(varbinary(max),c1),11,datalength(convert(varbinary(max),c1))))
from #t

drop table #t

per-Service SID

Rock 提了一個有趣的授權問題,Windows Vista 和 Windows Server 2008 後,服務可使用資源(例如檔案)的權利,是 Service Account 和 per-Service SID 所獲得授權的聯集,例如設定服務的帳戶是以下任一個系統帳戶:

image

但服務的 per-Service SID 不會變

image

而安裝時預設提供的檔案目錄授權,還是會因為有授權 per-Service SID 而不管採用什犘 Service Account,SQL Server Service 都可以存取

http://www.travisgan.com/2013/06/sql-server-service-account-and-per.html

https://msdn.microsoft.com/zh-tw/library/ms143504.aspx#Reviewing_ACLs

企業 IT 應該有自己的步調

最近 BtoC/CtoC 盛行,IT 的聲音一切都以 Google、Apple、Amazon 馬首是瞻,MS 的營收就 Visual Studio 的老闆所云,個人貢獻度高過企業,因此,應該也以滿足個人開發者為主。換句話說,以 BtoC 為重。我相信,整個 MS 現今的重點也是個人,因為企業短時間不會投資太多錢在開發中的雲上,個人與小企業才有彈性用不停變動的雲。傳統企業 IT 大廠如 Oracle、SAP、IBM 在這一波中失去了話語權。BtoB 和 BtoE 暫時失聲,如同 BPM、ERP、CRM、SCM、PLM、PKI、OA、EIP、BI 等企業名詞被 App、UX、Big Data、ML、IoT…等 BtoC 的名詞蓋過。

以下主要針對 BtoB 與 BtoE 類型的企業系統討論。

企業系統應有自己的生命周期,若一個系統從研發到穩定需要 3~5 年,甚至更長,則不使用 3~5 年乃至於更長,是不合成本。因為系統變動的 TCO 是驚人的,除了明顯的研發與採購成本外,還要包含生疏錯誤造成的損失,教育訓練至熟練而發揮其功能,收集使用經驗而最佳化,整合異質系統而發揮綜效…等等。但主要的系統平台廠商 MS 因應 BtoC 的潮流,將產品生命週期縮短至 1~2 年,甚有 1 季的。更糟的是如同 Silverlight 轉向 HTML5、Web Services/WCF 轉向 Web API、Ajax 轉向 Google 的 library/framework,在轉變的過程中,放棄相容性。或許,lean 變成了多方押寶試試看,見壞就收。

企業的 IT 資金與人力有排他性,只有依重要性先做,但重要性的決定權卻不在企業 IT。日昨跟一位大學教授聊天,他說 "該國立大學連題庫系統都沒有,似乎是停滯了十幾年。這次提教務需求時,居然被人事壓過去了"。類似的案例不勝枚舉,各企業、機構、法人都還有一堆系統沒做,盼望的功能很多年都等不到。而各系統輪動開發下,若每次採用不同的技術,將導致管理與整合困難,讓 IT 系統無法發揮綜效。在開發重大系統曠日廢時,而周邊系統往往要跟核心系統相容的時空下,企業越大,技術變動越慢。以往 MS 3~5 年的更版週期中,金融業以系統為單位,往往採取跳板升級,若換算成現在的更版週期,恐怕要跳多版了。而製造業向來是將本求利,系統用到不能用為止,很少在乎技術的生命週期或 EOS。

企業 IT 重 Domain Know-how,這往往在人的腦子裡,企業 IT 以單一技術,輪動開發不同系統,重點是最佳化 Domain know-how,若還要時時採用新技術,技術盲點將造成極大的系統不穩定與風險。而一旦這些 IT 人脫離新技術的腳步,往往也會拒斥新技術,因為舊有的成熟技術往往足以解決現有的企業 IT 問題,新技術還需要時間補足全面性的功能,期待有使用者反映給開發商告知如何最佳化,並等其再出個幾版以穩定解決方案,無解的問題也要等時間錘煉出 best practice 或 SOP。而舊有技術就算缺某些能力,往往也早有 workaround 的共識。

方法論有資源、文化與地域的侷限性。IT 方法論不管是早期的 RUP、MOF、CMMI 或當下流行的 Agile/Scrum/看板…往往是美國的產品廠商具有話語權,其他各國皆否。因此日系的管理風格配合不上美式作法,台式的低人事成本難以套用高人力成本孕育出的方法論。更別提建立方法論的大師多是做產品的,而非企業 IT。因為做產品才有主導權,可控制或影響時程、資源、功能與思想下,大師們才能同時探討方法論的理論與實務。企業 IT 的本質是 Dirty and Quick,不分國別皆如此。因為驅動與管理 IT 的皆非 IT 專業人士。不像做產品的廠家,若高階管理層不了解 IT 本質,這家公司也活不了多久,因此他們有適合開發軟體的方法論。但主導企業的是對該領域 Domain Know-how 瞭若指掌的人,不管他熟市場、人脈、金流、生產,還是產品或銷售,但絕不會是因精熟 IT 而當上企業老闆,也絕不想投資 MIS 的 R&D,他們腦子裡只有營運與 cost down,沒有 IT。沒有方法論經得起以下的挑戰:要有立竿見影的成效、削減人事支出導致的人事更迭、熟知企業運作的老 IT 人拒絕新方法、沒有開發軟體優先順序只有老闆隨時插件地撕扯排程,隨意 cost down 的軟硬體選擇,不管軟體架構優劣只有當下使用經驗好壞的架構抉擇,但這些才是各個部門主管拿手的絕活。

企業 IT 要一再地重構,但重點是在有限資源與時間內改善企業流程,而非漂亮的 IT 技術。採用 IT 技術須優先考量成本,在有限的預算下,IT 主管往往寧願留住人事薪資,購買新機器跑舊軟體,以擴充效能與容量。因為以新技術開發的成本高且風險大,不如選用舊技術重構企業流程。採用新技術代表終端使用者的重新適應、IT 人員的教育訓練、引入外部顧問與錯誤嘗試,而這些都是優先 cost down 掉的。且若一再換新技術與平台,如何重構?

企業 IT 的重點是支援與配合,重點不在技術,在善用有限資源。如何將既有的資源最大化,更新不是重點,穩定、可靠與加值才是。看國內的 IT 教育訓練機構、SI 或軟體開發商…等等的 MIS,這些以賣 IT 技術維生的公司的 MIS 有先進與完善嗎?他們的老闆應該已經是最接近 IT 技術的老闆了,他們的 MIS 應該有最充足的技術與方法論的支援。我曾當過許多這類公司的顧問,或實際參與其中,相信我,他們的 MIS 依然如同你我公司內的 MIS。因為本質是支援,重點的優先順序就不在 MIS 採用的 IT 技術與方法論。

以上表列企業 IT 與產品 IT 的差異,若你要追求 IT 技術的美,最好進入產品公司,或是做個人 SOHO,因為企業 MIS 乃至於接企業案子的 SI,其最高目的都是企業能以最低成本打造 IT,這裡往往沒有規劃,你永遠也摸不清老闆的優先排程。隨機應變才是強者,因此,閉著眼睛也可以操控特定的技術與平台才是你的價值,而非搜尋探索新技術黑洞的能力。

若你是企業 IT 主管,你需要拿捏引入新技術的時機,畢竟,當你新聘、尋求支援與委外時,可能因沒有舊技術的資源而不得不然。如何模組化、介面化、平台化與服務化後,漸進導入新技術,並賦予價值,再推銷給老闆,將是你最大的課題。你要有自己的方法論,在尊重存在即有理的前提下,嘗試在新方法論中找出你企業裡少數可用的元素,有耐心地將其融入既有流程,建立符合企業生態的文化,才有可能持續地運轉。此外,你們公司的 IT 步調只有你能建議。但未摸清老闆的優先順序前,勿輕易開口或擅自決定。當然,我想你也可能不在乎這一切,因為當下的位子只是跳板。

重設 Identity 接下來遞增的值

USE tempdb;
GO
create table t(c1 int identity primary key)
go
insert t default values
go 20

delete t where c1 < 10
go

DBCC CHECKIDENT (‘t’, RESEED,1);
go

–加一筆 2
insert t default values
go
select * from t
GO

 

set identity_insert t on
go
insert t(c1) values(5)
select * from t
go

set identity_insert t off
go

–加一筆 6
insert t default values
select * from t
go

–違反 PK Error
insert t default values
go 20

訊息 2627,層級 14,狀態 1,行 34
違反 PRIMARY KEY 條件約束 ‘PK__t__3213663BA6D0B54B’。無法在物件 ‘dbo.t’ 中插入重複的索引鍵。重複的索引鍵值是 (10)。
陳述式已經結束。
** 執行批次時發現錯誤。正在繼續。

drop table t

關注

有新文章發表時,會立即傳送至你的收信匣。

加入其他 27 位關注者