【问题标题】:SQL Server stored procedure passing parameters into variablesSQL Server 存储过程将参数传递给变量
【发布时间】:2015-12-20 15:51:18
【问题描述】:

我有一个有效的大查询,我想为它编写一个存储过程。 我收到此错误:

链接服务器 "theServer" 的 OLE DB 提供程序 SQLNCLI11" 不包含表 ""@dbName"."dbo"."tableName"

我想做什么:

create PROCEDURE [sys.sp_myProcedure] 
(
 @dbName varchar(30) output, 
 @rid varchar (10) output,
 @mdate output
 )
AS
BEGIN
declare @prt varchar(12)
declare @pid int
declare @cid int
--declare @rid int
declare @aid int

    SET NOCOUNT ON;
set @cid= (select CID from  theServer.[@dbName].dbo.tableName where RID= @rid)
set @pid= (select PID from  theServer.[@dbName].dbo.tableName where RID= @rid)
set @aid= (select aid from  theServer.[@dbName].dbo.tableName where RID= @rid)
--then my query begins

theServer.[@dbName].dbo.tablename 是一个链接服务器。

我想做的是:

execute [sys.sp_myProcedure] 'someDbname', '123', '2012-03-03'

这里传递的参数将在运行时设置/更新变量@dbName, @rid, @mdate。 (@mdate 我在查询中把它放在更远的地方,它太大了,无法用 myTable 调整它并更改所有敏感数据)。

我该怎么做? (使用 SQL Server 2012)

编辑(基于 cmets 和答案):

所以,它是 @thatString = '--insert the query here ' 。那么,在我的情况下,如何根据查询中的参数设置这些变量?我应该用替换来做吗?像这样:set @thatString= replace(@thatString, dbName, @dbname)

**

编辑 2

**

set @sql = '
use [someDbName];
use [123];
use [2012-03-03];

select ... '
set @sql = replace (@sql, 'someDbName', @dbName)
set @sql = replace (@sql, '123', @rid)
set @sql = replace (@sql, '2012-03-03', @mdate)
execute @sql
end

我做对了吗? execute @sql 在正确的位置吗?

我问是因为它不起作用。我得到了名字' --part of my query here' is not a valid identifier

【问题讨论】:

  • 您不能在 T-SQL 中参数化 names。您必须将整个内容构建为一个大字符串并将其传递给 EXEC(也称为动态 SQL)
  • 我明白了,请看我的编辑,如果我明白了,请告诉我
  • 旁注:您应该为您的存储过程使用sp_ 前缀。微软有reserved that prefix for its own use (see Naming Stored Procedures),你确实会在未来某个时候冒着名称冲突的风险。 It's also bad for your stored procedure performance。最好只是简单地避免 sp_ 并使用其他东西作为前缀 - 或者根本不使用前缀!
  • 哦,不知道。谢谢

标签: sql database stored-procedures dynamic sql-server-2012


【解决方案1】:

不能从变量中动态指定数据库或其他对象的名称。解决方法是在一个字符串中编写一个动态 SQL 查询,将所需的名称连接到该字符串中,然后将 execute (@thatString) 连接起来。

(您可能认为您可以使用use,但它的作用域是您必须将查询的其余部分包含在同一个执行的字符串中。)

--

根据要求编辑更多信息。您可以随心所欲地编写字符串。如果您需要更多指导,这里有很多讨论动态 T-SQL 的页面。但是,嘿,两个想法:

set @myDynamicQuery =
'
    use [' + @myDynamicDatabase + '];

    select BLAH from WHOM where DATA = ''what'';
';

或者,如果您将经常使用该名称,则可以减少因插入和取出单引号引起的麻烦,如下所示 - 尽管我个人从不使用它,因为我不喜欢它的外观:

set @myDynamicQuery =
'
    use [A_RARE_PLACEHOLDER];

    select BLAH from WHOM where DATA = ''what'';

    -- lots more uses of A_RARE_PLACEHOLDER
';

set @myDynamicQuery = replace(
    @myDynamicQuery,
    'A_RARE_PLACEHOLDER',
    @myDynamicDatabase
);

然后execute (@myDynamicQuery);

【讨论】:

  • 谢谢你,但我是新手。只是为了确保:我是否在存储过程声明中声明了@myDynamicDatabase?我也可以使用这个 3 次(因为我有 3 个参数?)像这样:use [' + @dbName + ']; 然后use [' + @rid+ ']; 'use [' + @mDate+ '];`
  • 你真的尝试过这些吗?如果是这样,请遵循 IT 标准:您尝试过什么?你期望会发生什么?反而发生了什么?此外,您删除了您的接受投票很奇怪,因为我确实回答了您最初提出的问题。如果 - 在实际尝试代码之后 - 您有不同的问题,则应分别提出;我不是 SO 方面的专家,但我认为不断移动现有问题的目标是不礼貌的。
  • 你是对的,你回答了我的问题,因此接受。我解决了与语法相关的问题。现在我有一个临时表空间分配问题。但正如你所说,这是另一个问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多