【问题标题】:DB name as parameter in user-defined functionDB名称作为用户定义函数中的参数
【发布时间】:2014-01-15 16:51:03
【问题描述】:

是否可以在自定义函数中使用数据库名作为参数?

例如,我尝试使用连接,但它不能以这种方式工作:

create function fn_getEntityOwners (@dbName varchar, @entityId bigint)
returns table
as
return 
select
    OWNERS.USER_ID 
from 
    @dbName + '.dbo.OWNERS' as OWNERS
where 
    OWNERS.ENTITY_ID = @entityId

更新:我使用 sql server

【问题讨论】:

  • @AndriyM 我的问题更具体,因为我需要在用户定义的函数中使用数据库名称作为参数,并且函数施加了一些限制。
  • 好吧,你不能参数化一个 name(数据库名、列名、表名)。几乎所有的答案(那里和这里)都建议使用动态 SQL。您不能在函数中使用动态 SQL,这意味着您对 this specific question 无能为力。我建议您提出一个新问题,您可能想在其中详细说明您正在尝试做什么,以及您会在哪里专门询问使用动态 SQL 的替代方案(或者,也许是使用函数的替代方案?) .
  • 感谢您的建议,我已经添加了一个新问题link

标签: sql-server


【解决方案1】:

将你的代码放入函数中,并通过动态sql执行

DECLARE @SQL varchar(2000)

SELECT @SQL = 

'select
    OWNERS.USER_ID 
from 
    ' + @dbName + '.dbo.OWNERS as OWNERS
where 
    OWNERS.ENTITY_ID = ' + @entityId


EXEC(@SQL)

【讨论】:

  • 不太喜欢这种方法,因为查询变成了字符串,并且没有经过 SQL Server Management Studio 的验证。但无论如何,谢谢你的解决方案。其他想法?
  • 您是否担心数据库不存在并抛出错误?如果是这样,总是可以在查询 user_id 之前添加代码来检查是否存在...如果 db_id(@dbName) IS NOT NULL BEGIN...
  • 不,我担心你在sql查询中出错的情况,但因为它只是一个字符串,你只有在函数执行后才会知道这一点。我只展示了一个简单的示例,但想象一下函数内部的查询既庞大又复杂。
  • 函数中不能使用exec
【解决方案2】:

您需要使用动态 SQL 来执行此操作。这是什么数据库? Here's 另一个相关的 SO 问题

【讨论】:

  • 太好了,SQL Server 将支持动态 SQL。
  • 查看我对@DominionDave 的评论
【解决方案3】:

您也可以为此使用sqlcmd 模式(在 Management Studio 的“查询”菜单上启用此功能)。

:setvar dbname "TEST.dbo.OWNERS" 

select
    OWNERS.USER_ID 
from 
    $(dbname) as OWNERS
where 
    OWNERS.ENTITY_ID = @entityId


...这个解决方案由Stack Overflow 提供给您...

whatup @DominionDave - 很高兴有你在 SO playa :-D

【讨论】: