2015-10-22 77 views
0

我遇到了一個很奇怪的問題,可以重複。基本上,我使用invoke-sqlcmd通過使用-inputfile來調用腳本文件,但是如果腳本文件有一些執行錯誤(例如插入列不應該爲空的表),腳本文件將是執行兩次。我也可以從profiler中看到這兩個執行。Invoke-Sqlcmd運行腳本兩次

下面是重現該問題的方式(我的環境:贏8.1 + SQL2014 + PS 5.0)

  1. 在數據庫中創建兩個表

    Use TestDB 
    
    create table dbo.s (id int identity primary key, b varchar(50)); 
    
    create table dbo.t (id int primary key, s_id int, b varchar(50)); 
    alter table dbo.t add constraint fk_t foreign key (s_id) references dbo.s(id) 
    
  2. 現在創建一個SQL文件(我們稱之爲c:\ temp \ t.sql)用以下兩行代碼

    insert into dbo.s (b) select 'hello world' 
    insert into dbo.t (s_id, b) -- purposely missing id to cause an error 
    select 1, 'good morning' 
    
  3. 運行以下PS cmdlet的

    invoke-sqlcmd -Server "<my_local_server>" -database TestDB -inputfile "c:\temp\t.sql" 
    

你的PS,如果你打開一個SSMS查詢窗口將返回一個錯誤,現在執行下列操作

select * from TestDB.dbo.s 

你會看到兩個記錄存在,而不是一個。 Two records 另一方面,如果我運行sqlcmd.exe,則不存在這樣的問題,即只有dbo中有一條記錄。 我錯過了SQLPS中的一些配置嗎?

+0

可重現。也許dba.stackexchange.com人們有更多的見解,所以我會投票支持遷移。 – vonPryz

回答

1

我看到你在MSDN數據庫引擎論壇上提出了同樣的問題:https://social.msdn.microsoft.com/Forums/en-US/d4167226-2da7-49ec-a5c2-60e964785c2c/powershell-invokesqlcmd-calls-stored-procedure-second-time-after-query-timeout-is-expired。以下是該線程的SMO解決方法。

$SqlServreName = "YourServer"; 
$DatabaseName = "YourDatabase"; 
$ScriptFileName = "C:\Scripts\YourSqlScriptFile.sql"; 

Add-Type -Path "C:\Program Files\Microsoft SQL Server\110\SDK\Assemblies\Microsoft.SqlServer.Smo.dll"; 

$sr = New-Object System.IO.StreamReader($ScriptFileName); 
$script = $sr.ReadToEnd(); 
$sr.Close(); 

$Server = New-Object Microsoft.SqlServer.Management.Smo.Server($DatabaseName); 
$db = $Server.Databases[$DatabaseName]; 
$db.ExecuteNonQuery($script); 
+0

謝謝@丹。我知道解決這個問題的另一種方法,因爲當我使用invoke-sqlcmd2(sqlpsx [鏈接](https://sqlpsx.codeplex.com/)中的一個使用System.Data.SqlClient.SqlCommand的函數)時,沒問題,我想我的問題或擔心應該是「這是SQLPS模塊的大錯誤」 – jyao

1

即使我有類似的問題。

通過向Invoke-Sqlcmd cmdlet中添加-QueryTimeout參數來修復它。

基本上看來,查詢以某種方式超時,並且由於Invoke-Sqlcmd cmdlet中的錯誤,它試圖再次插入它。奇怪,但試試這個。使查詢超時足夠大,以便執行查詢。

0

我知道這是一個古老的線程,但也許它可以幫助某人。

我發現如果你在插入語句之前移動你的行「select 1,'早上好''」,它有一個例外,它像預期的那樣工作。

我有一個與try catch類似的問題,當它是一個異常時,第一個返回值將被忽略,所以我必須確保第一行是Select 1.奇怪的錯誤。