【问题标题】:Using stored procedure parameters to return columns使用存储过程参数返回列
【发布时间】:2023-03-10 20:30:02
【问题描述】:

我正在尝试编写一个基于两个输入参数返回特定值的存储过程。问题是试图使其中一个参数引用一列。

这是我的桌子:

CityID      CityName             London                               Paris                                   
----------- -------------------- --------------------------------------- --
1           London               0                                       60                                      
2           Paris                50                                      0                                       
3           Berlin               90                                      60                                      
4           Madrid               150                                     90                                      
5           Dublin               30                                      80                                      
6           Rome                 75                                      88    

是否可以按照以下方式编写存储过程:

CREATE PROCEDURE Price (@city1, @city2)
AS
    SELECT @city2 
    FROM dbo.MyTable
    WHERE CityName = @city1

【问题讨论】:

  • 你描述的是动态SQL。您想传入列的名称,然后返回匹配城市的该列的值。对吗?
  • 是的,完全正确。恐怕我对 Dynamic Sql 不熟悉。
  • 如果不了解您使用的 RDBMS,则无法准确回答此问题。看起来像 MS SQL 但请与版本一起确认。
  • 是的,它的 MS SQL。我正在使用 SQL Server 2016。

标签: sql database stored-procedures sql-server-2016


【解决方案1】:

我会做这样的事情,在尝试运行动态 SQL 语句之前验证列名的存在:

create procedure dbo.GetPrice(@city nvarchar(50), @column nvarchar(200)) as
begin

if (not exists (select *
                from sys.columns
                where object_id = object_id('dbo.MyTable') and name = @column))
    return;
else begin
    declare @sql nvarchar(max) =
        'SELECT [' + @column + '] FROM dbo.MyTable WHERE CityName = ''' + @city + '''';

    execute sp_ExecuteSQL @sql;
end;

end;

【讨论】:

  • 我收到“将数据类型 varchar 转换为数字时出错。”目前我不需要检查列是否存在。
  • 我刚刚在本地测试过,运行execute dbo.GetPrice 'test', 'London';时它运行良好
  • 目前我不需要检查列的存在。如果你想避免人们运行任意 SQL 语句,这是必要的。
【解决方案2】:

你将不得不使用动态 sql。

CREATE PROC Price (@City1, @City2)
AS 
BEGIN
DECLARE @Sql NVARCHAR(MAX)
SET @Sql = 'SELECT ' + @City2 + ' FROM dbo.MyTable WHERE CityName = ''' + 
@City1 +  ''''

EXEC sp_execute @Sql
END

【讨论】:

  • 这不解析。不仅如此,如果有人通过@City2 = '0; drop table users; select null'你打算怎么做
【解决方案3】:

创建过程 [dbo].[USP_Price] @city1 瓦尔查尔, ------------------------------------------------ @City2 VARCHAR(MAX) = NULL OUT

作为 开始

 SELECT @city2 
FROM dbo.MyTable
WHERE CityName = @city1

结束

--- 创建存储过程,如果你使用的是sql server, 右键单击存储过程,然后单击执行存储过程 输入 city1 值,同时为城市 2 选择 null 并执行

【讨论】:

  • 尝试使用上面的查询创建存储过程
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-18
  • 1970-01-01
  • 1970-01-01
  • 2013-01-11
  • 1970-01-01
  • 2011-01-17
  • 2012-12-17
相关资源
最近更新 更多