【问题标题】:Stored procedure not setting variable存储过程未设置变量
【发布时间】:2022-01-26 15:36:29
【问题描述】:

我尝试过但不明白我的代码有什么问题。我正在尝试在调用第二个存储过程的存储过程中设置一个变量,但我知道结果,我知道该变量设置不正确。谁能说出我的错误在哪里。

CREATE PROCEDURE [dbo].[ColumnHasData]
    @scheme VARCHAR(10),
    @tablename VARCHAR(30),
    @column VARCHAR(50)
AS
BEGIN

    DECLARE @FullQuery NVARCHAR (max)=N'
        IF EXISTS
        (
            SELECT *
            FROM ' + @scheme + '.' + @tablename + '
            WHERE [' + @column + '] IS NOT NULL
        )
        SELECT CAST(1 AS BIT)
        ELSE 
        SELECT CAST(0 AS BIT)
    ';

    EXECUTE sp_executesql @FullQuery;
END

CREATE PROCEDURE [dbo].[me_delete_column]
AS
BEGIN

    Declare @noDataPresent bit
    
    exec @noDataPresent = [different_db].[dbo].[ColumnHasData] 'int' ,'table1' ,'column1'

    print @noDataPresent

    RETURN
    IF(@noDataPresent=0)
    begin
        --drop column
    end
    
END

ColumnHasData 在一个数据库中

me_delete_column 在第二个数据库中

我正在尝试设置变量 @noDataPresent 执行 ColumnHasData

即使我知道结果应该是 1 print @noDataPresent 返回 0 所以出了点问题。

出了什么问题,为什么我的变量没有设置? SQL Server 版本为 15.0.4102.2

【问题讨论】:

  • 您的程序dbo.ColumnHasData 没有返回任何内容?要“返回”一个值(旨在作为 SP 的状态),需要使用 RETURN 语句。
  • 您不使用过程返回的 resultset,而是像返回一个 returncode 一样调用它,它始终是一个 int.
  • 所以我应该设置一个变量用sp_executesql 返回然后返回?
  • 那个过程是危险的;它很容易受到注入攻击。如果您必须使用动态 SQL,总是QUOTENAME 正确引用您的对象。尽管这看起来您已经尝试创建“一刀切”的动态过程,但这并不是一个好主意。 SQL 不是脚本语言,不要像脚本语言那样写。
  • @HellOfACode 你真的需要阅读docs 来发现输出参数、返回值和结果集之间的区别。

标签: sql sql-server tsql stored-procedures


【解决方案1】:

使用输出参数从存储过程传递标量值。唯一有点棘手的部分是在动态 SQL 中设置参数。

EG

CREATE PROCEDURE [dbo].[ColumnHasData]
    @schema NVARCHAR(128),
    @tablename NVARCHAR(128),
    @column NVARCHAR(128),
    @hasData bit output
AS
BEGIN

    DECLARE @FullQuery NVARCHAR (max)=N'
        IF EXISTS
        (
            SELECT *
            FROM ' + quotename(@schema) + '.' + quotename(@tablename) + '
            WHERE ' + quotename(@column) + ' IS NOT NULL
        )
        set @hasData = CAST(1 AS BIT)
        ELSE 
        set @hasData = CAST(0 AS BIT)
    ';

    EXECUTE sp_executesql @FullQuery, N'@hasData bit output', @hasData = @hasData output;
END

样本数据

use tempdb 
drop table if exists t 
create table t(id int, a int null)
insert into t(id,a) values (1,null)

用法:

declare @hasData bit
exec ColumnHasData 'dbo','t','id', @hasData output

select @hasdata 

declare @hasData bit
exec ColumnHasData 'dbo','t','a', @hasData output

select @hasdata 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-06
    • 2012-06-20
    • 1970-01-01
    • 2015-04-05
    • 1970-01-01
    • 1970-01-01
    • 2012-03-03
    相关资源
    最近更新 更多