0

我有一個存儲過程,我正在努力,我試圖讓它返回存儲在我創建的過程中的表變量的結果。出於某種原因,當我執行該程序時,它不返回任何內容。但是,如果我拿一塊用來填充表變量並取出它的工作程序代碼...存儲過程不返回表變量的結果?

的代碼如下:

測試代碼

DECLARE @RC int 
DECLARE @constraint_names nvarchar(max) 
DECLARE @column_names nvarchar(max) 
DECLARE @table_name nvarchar(max) 
DECLARE @table_schema nvarchar(max) 
DECLARE @database_name nvarchar(max) 
DECLARE @debug int 
DECLARE @ExistFlag int; 

-- TODO: Set parameter values here. 
SET @column_names = 'M2016_Object_ID int, Name varchar(50), a int, b' 
SET @table_name = 'tblM2016_Objects'; 
SET @debug = 0; 
SET @ExistFlag = 1; 

DECLARE @existing_cols TABLE (Value nvarchar(max)); 
INSERT INTO @existing_cols EXEC spM2016_CheckColumnExistence_tblM2016 
@column_names, @table_name, @database_name, @table_schema, 1, 0; 
select * from @existing_cols 

結果

Value 
M2016_Object_ID int 
Name varchar(50) 

這是預期的結果,因爲我測試查看tblM2016_Objects表中是否存在M2016_Object_ID和Name列。

但是,當我在存儲過程中執行此操作時,它不返回任何內容。

存儲過程

ALTER PROCEDURE spM2016_ChangePKConstraints_tblM2016 
-- Add the parameters for the stored procedure here 
    @constraint_names nvarchar(max) = 
N'PK_tblM2016_Fields_M2016_Field_ID', 
    @column_names  nvarchar(max) = N'M2016_Field_ID', 
    @table_name   nvarchar(max) = N'tblM2016_Fields', 
    @table_schema  nvarchar(max) = N'dbo', 
    @database_name  nvarchar(max) = N'MET', 
    @debug    int = 0 
AS 
BEGIN 
-- SET NOCOUNT ON added to prevent extra result sets from 
-- interfering with SELECT statements. 
SET NOCOUNT ON; 

-- Insert statements for procedure here 
DECLARE @tbl_name  nvarchar(max) = N'tblM2016_Fields', 
     @col_names  nvarchar(max) = N'M2016_Field_ID', 
     @tbl_schema  nvarchar(max) = N'dbo', 
     @db_name  nvarchar(max) = N'MET', 
     @tbl_full_name nvarchar(max), 
     @tbl_short_name nvarchar(max), 
     @sql   nvarchar(max), 
     @params   nvarchar(max) 

-- Insert statements for procedure here 

SET @col_names = ISNULL(NULLIF(@column_names, ''), @col_names); 
SET @tbl_name = quotename(ISNULL(NULLIF(@table_name, ''), @tbl_name)); 
SET @tbl_schema = quotename(ISNULL(NULLIF(@table_schema, ''), @tbl_schema)); 
SET @db_name = quotename(ISNULL(NULLIF(@database_name, ''), @db_name)); 

SET @tbl_full_name = @db_name + '.' + @tbl_schema + '.' + @tbl_name; 
SET @tbl_short_name = @tbl_schema + '.' + @tbl_name; 

DECLARE @existing_cols TABLE (Value nvarchar(max)); 
DECLARE @nonexisting_cols TABLE (Value nvarchar(max)); 

--INSERT INTO @split_columns 
-- SELECT * 
-- FROM 
-- fnM2016_Split_String_Inline(@col_names, ','); 

--IF (@debug = 1) 
-- SELECT * FROM @split_columns; 

IF NOT EXISTS (SELECT * FROM sys.objects WHERE type = 'PK' AND parent_object_id = OBJECT_ID(@tbl_full_name)) 
BEGIN 
    -- No PK constraint, check col_names to see which exist and don't exist 
    INSERT INTO @existing_cols EXEC spM2016_CheckColumnExistence_tblM2016 @col_names, @tbl_name, @db_name, @tbl_schema, 1, 0; 

    INSERT INTO @nonexisting_cols EXEC spM2016_CheckColumnExistence_tblM2016 @col_names, @tbl_name, @db_name, @tbl_schema, 0, 0; 

    SELECT * FROM @existing_cols; 

    SELECT * FROM @nonexisting_cols; 

END 
--ELSE 
--BEGIN 

--END 

END 

結果 這些是在測試用相同的參數值執行上述步驟之後的結果:

EXECUTE @RC = [dbo].[spM2016_ChangePKConstraints_tblM2016] 
@constraint_names 
,@column_names 
,@table_name 
,@table_schema 
,@database_name 
,@debug; 

結果

Value 

該表故意沒有主鍵。證明: enter image description here

+0

在你的程序中,你有表的名稱爲'@table_name爲nvarchar(MAX)= N'tblM2016_Fields'',但它應該是' tblM2016_Objects' –

+0

您可以顯示您傳遞給'spM2016_ChangePKConstraints_tblM2016'過程的實際值嗎? –

+0

測試代碼塊中使用的參數與傳遞給spM2016_ChangePKConstraints_tblM2016的參數相同。 – Jake

回答

1

在您的過程中,更改「聲明」部分中表的名稱。

這應該解決這個問題。

ALTER PROCEDURE spM2016_ChangePKConstraints_tblM2016 
-- Add the parameters for the stored procedure here 
    @constraint_names nvarchar(max) = 
N'PK_tblM2016_Fields_M2016_Field_ID', 
    @column_names  nvarchar(max) = N'M2016_Field_ID', 
    @table_name   nvarchar(max) = N'tblM2016_Objects', 
    @table_schema  nvarchar(max) = N'dbo', 
    @database_name  nvarchar(max) = N'MET', 
    @debug    int = 0 
AS 
BEGIN 
-- SET NOCOUNT ON added to prevent extra result sets from 
-- interfering with SELECT statements. 
SET NOCOUNT ON; 

-- Insert statements for procedure here 
DECLARE @tbl_name  nvarchar(max) = N'tblM2016_Objects', 
     @col_names  nvarchar(max) = N'M2016_Field_ID', 
     @tbl_schema  nvarchar(max) = N'dbo', 
     @db_name  nvarchar(max) = N'MET', 
     @tbl_full_name nvarchar(max), 
     @tbl_short_name nvarchar(max), 
     @sql   nvarchar(max), 
     @params   nvarchar(max) 
+0

參數順序,我不認爲這工作,因爲我spM2016_CheckColumnExistence具有相同的默認參數並不會導致它,當我在直接把它稱作失敗測試代碼。這些值主要用於null比較,以防表名參數傳遞給null或空字符串。 – Jake

0

我想出了這個問題。我的@table_name,@table_schema@database_name被傳遞到過程中spM2016_ChangePKConstraints_tblM2016已通過調用quotename()逃脫。在spM2016_CheckColumnExistence_tblM2016內部,我還對qutoename()的參數進行了驗證檢查,以檢查壞表,數據庫和模式名稱。該程序代碼被遺漏了,我對此表示歉意。

本質問題區域在這裏spM2016_ChangePKConstraints_tblM2016(有問題的參數強調了與**)

問題代碼

INSERT INTO @existing_cols EXEC spM2016_CheckColumnExistence_tblM2016 @col_names, **@tbl_name**, **@db_name**, **@tbl_schema**, 1, 0; 

注意,被傳遞到spM2016_CheckColumnExistence_tblM2016這些參數已經逃脫了quotename()以上在spM2016_ChangePKConstraints_tblM2016程序中。現在,這裏是在spM2016_CheckColumnExistence_tblM2016程序丟失關鍵代碼:在spM2016_CheckColumnExistence_tblM2016

問題代碼

ALTER PROCEDURE spM2016_CheckColumnExistence_tblM2016 
-- Add the parameters for the stored procedure here 
@column_names nvarchar(max) = N'M2016_Field_ID int', 
@table_name  nvarchar(max) = N'tblM2016_Fields', 
@database_name nvarchar(max) = N'MET', 
@table_schema nvarchar(max) = N'dbo', 
@ExistFlag  int   = 1,      -- Check for column existence in given table = 1 
                 -- Check for column non-existence in given table = 0 
@debug   int   = 0      
AS 
BEGIN 
-- SET NOCOUNT ON added to prevent extra result sets from 
-- interfering with SELECT statements. 
SET NOCOUNT ON; 

-- Insert statements for procedure here 
DECLARE @tbl_name  nvarchar(max) = N'tblM2016_Fields', 
     @col_names  nvarchar(max) = N'M2016_Field_ID', 
     @tbl_schema  nvarchar(max) = N'dbo', 
     @db_name  nvarchar(max) = N'MET', 
     @tbl_full_name nvarchar(max), 
     @tbl_short_name nvarchar(max) 

-- Insert statements for procedure here 

***** PROBLEM STARTS HERE ***** 
SET @col_names = ISNULL(NULLIF(@column_names, ''), @col_names); 
SET @tbl_name = quotename(ISNULL(NULLIF(@table_name, ''), @tbl_name)); 
SET @tbl_schema = quotename(ISNULL(NULLIF(@table_schema, ''), @tbl_schema)); 
SET @db_name = quotename(ISNULL(NULLIF(@database_name, ''), @db_name)); 

SET @tbl_full_name = @db_name + '.' + @tbl_schema + '.' + @tbl_name; 
SET @tbl_short_name = @tbl_schema + '.' + @tbl_name; 

我突出問題與*****問題從這裏開始*****爲清楚起見。正如你所看到的,spM2016_CheckColumnExistence_tblM2016也做了quotename調用,以確保傳遞給spM2016_CheckColumnExistence_tblM2016@table_name@table_schema@database_name也有適當的轉義。但是,因爲我通過已經quotenamed @table_name@table_schema@database_namespM2016_ChangePKConstraints_tblM2016spM2016_CheckColumnExistence_tblM2016@col_names, @tbl_name, @db_name, @tbl_schema,他們得到了雙引號和spM2016_CheckColumnExistence_tblM2016做的sys.object查詢比較時是這樣面目全非等正在返回假的結果。

測試代碼工作的原因是因爲參數在傳遞到spM2016_CheckColumnExistence_tblM2016時尚未轉義,從而導致表變量執行正常。

事實證明,它沒有任何關係與表變量:/

相關問題