我有一个我正在处理的存储过程,并且我试图让它返回存储在我在过程中创建的表变量中的结果。出于某种原因,我执行程序时没有返回任何内容。但是,如果我使用用于填充表变量的代码片段并将其从程序中删除它...
代码如下:
测试代码
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
答案 0 :(得分:1)
在您的程序中,更改Declare部分中表格的名称。
这应解决问题。
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)
答案 1 :(得分:0)
我想出了这个问题。传递到@table_name
内的@table_schema
程序的@database_name
,spM2016_CheckColumnExistence_tblM2016
和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
也会进行引号调用,以确保传递给@table_name
的{{1}},@table_schema
和@database_name
也具有正确的转义权限。但是,由于我将spM2016_CheckColumnExistence_tblM2016
,@table_name
和@table_schema
从@database_name
传递到spM2016_ChangePKConstraints_tblM2016
作为spM2016_CheckColumnExistence_tblM2016
,因此我们将其引用了双引号因此在@col_names, @tbl_name, @db_name, @tbl_schema
中的sys.object查询中进行比较时无法识别,因此返回虚假结果。
测试代码工作的原因是因为参数在传递到spM2016_CheckColumnExistence_tblM2016
时尚未转义,从而导致表变量执行正常。
原来,它与表变量无关:/