Sql server 在SQL多部分标识符中连接数据库名称
我正在编写一个存储过程,并试图将数据库名称连接到多部分标识符中的Sql server 在SQL多部分标识符中连接数据库名称,sql-server,sql-server-2012,Sql Server,Sql Server 2012,我正在编写一个存储过程,并试图将数据库名称连接到多部分标识符中的FROM之后,但没有成功。这是我尝试过的一种方法,但没有成功 INSERT INTO CONTROL_LOGISTICA.dbo.ITEMS_TRAMITE (NRODCTO, TIPODCTO, PRODUCTO, EMPRESA, CODUSUARIO, CODUBICA, CANTIDAD, CCHECK_HIJO) SELECT @pNrodcto, @pTipodcto, M.
FROM
之后,但没有成功。这是我尝试过的一种方法,但没有成功
INSERT INTO CONTROL_LOGISTICA.dbo.ITEMS_TRAMITE (NRODCTO, TIPODCTO, PRODUCTO, EMPRESA, CODUSUARIO, CODUBICA, CANTIDAD, CCHECK_HIJO)
SELECT
@pNrodcto, @pTipodcto,
M.PRODUCTO, @pEmpresa, @pUsuario,
M.CODUBICA, M.CANTIDAD, 0
FROM
"@mEmpresa".dbo.MVTRADE M WITH(NOLOCK) -- Here I'm stuck
INNER JOIN
Dbo.vReporteMercia_ESP P ON P.PRODUCTO = M.PRODUCTO
WHERE
M.CANTIDAD <> 0 AND M.Origen = 'FAC'
AND M.NRODCTO = @pNrodcto AND M.TIPODCTO = @pTipodcto
我知道如果我喜欢,我可以做一个
IF (@pEmpresa = 'John Doe')
BEGIN
--..... and the query here
END
是否可以使用变量连接数据库名称?怎么用?或者我应该只使用IF
?来执行类似的操作
declare @sql nvarchar(max);
declare @params nvarchar(max);
set @params= N'@pNrodcto int, @pTipodcto int, @pUsuario int, @pEmpresa char(20)';
set @sql = N'INSERT INTO CONTROL_LOGISTICA.dbo.ITEMS_TRAMITE (NRODCTO, TIPODCTO, PRODUCTO, EMPRESA, CODUSUARIO, CODUBICA, CANTIDAD, CCHECK_HIJO)
SELECT @pNrodcto,@pTipodcto,M.PRODUCTO,@pEmpresa,@pUsuario,M.CODUBICA,M.CANTIDAD,0
FROM '+db_name(db_id(@pEmpresa))+'.dbo.MVTRADE M WITH(NOLOCK) --Here im stuck
INNER JOIN Dbo.vReporteMercia_ESP P ON P.PRODUCTO = M.PRODUCTO
WHERE M.CANTIDAD <> 0 AND M.Origen = ''FAC''
AND M.NRODCTO = @pNrodcto AND M.TIPODCTO = @pTipodcto';
exec sp_executesql @sql, @params, @pNrodcto, @pTipodcto, @pUsuario, @pEmpresa;
declare@sql-nvarchar(最大值);
声明@params nvarchar(最大值);
设置@params=N'@pNrodcto int、@pTipodcto int、@pUsuario int、@pEmpresa char(20)';
设置@sql=N'插入控件\u LOGISTICA.dbo.ITEMS\u TRAMITE(NRODCTO、TIPODCTO、PRODUCTO、EMPRESA、CODUSUARIO、CODUBICA、CANTIDAD、CCHECK\u HIJO)
选择@pNrodcto、@pTipodcto、M.PRODUCTO、@pEmpresa、@pUsuario、M.CODUBICA、M.CANTIDAD、0
从“+db_name(db_id(@pEmpresa))+”.dbo.mvm到(NOLOCK)——我被卡住了
P.PRODUCTO=M.PRODUCTO上的内部连接Dbo.vReporteMercia\u ESP
其中M.CANTIDAD 0和M.Origen=“FAC”
M.NRODCTO=@pNrodcto和M.TIPODCTO=@pTipodcto';
exec sp_executesql@sql、@params、@pNrodcto、@pTipodcto、@pUsuario、@pEmpresa;
为了避免将参数直接连接到已执行的sql字符串,我将参数包装在对db\u name()
和db\u id()
的调用中。这将为无效的数据库名称返回null,但不会阻止某人引用您不希望他们引用的数据库。考虑将参数值与白名单进行比较。
参考:
您必须使用动态sql来完成类似的操作
declare @sql nvarchar(max);
declare @params nvarchar(max);
set @params= N'@pNrodcto int, @pTipodcto int, @pUsuario int, @pEmpresa char(20)';
set @sql = N'INSERT INTO CONTROL_LOGISTICA.dbo.ITEMS_TRAMITE (NRODCTO, TIPODCTO, PRODUCTO, EMPRESA, CODUSUARIO, CODUBICA, CANTIDAD, CCHECK_HIJO)
SELECT @pNrodcto,@pTipodcto,M.PRODUCTO,@pEmpresa,@pUsuario,M.CODUBICA,M.CANTIDAD,0
FROM '+db_name(db_id(@pEmpresa))+'.dbo.MVTRADE M WITH(NOLOCK) --Here im stuck
INNER JOIN Dbo.vReporteMercia_ESP P ON P.PRODUCTO = M.PRODUCTO
WHERE M.CANTIDAD <> 0 AND M.Origen = ''FAC''
AND M.NRODCTO = @pNrodcto AND M.TIPODCTO = @pTipodcto';
exec sp_executesql @sql, @params, @pNrodcto, @pTipodcto, @pUsuario, @pEmpresa;
declare@sql-nvarchar(最大值);
声明@params nvarchar(最大值);
设置@params=N'@pNrodcto int、@pTipodcto int、@pUsuario int、@pEmpresa char(20)';
设置@sql=N'插入控件\u LOGISTICA.dbo.ITEMS\u TRAMITE(NRODCTO、TIPODCTO、PRODUCTO、EMPRESA、CODUSUARIO、CODUBICA、CANTIDAD、CCHECK\u HIJO)
选择@pNrodcto、@pTipodcto、M.PRODUCTO、@pEmpresa、@pUsuario、M.CODUBICA、M.CANTIDAD、0
从“+db_name(db_id(@pEmpresa))+”.dbo.mvm到(NOLOCK)——我被卡住了
P.PRODUCTO=M.PRODUCTO上的内部连接Dbo.vReporteMercia\u ESP
其中M.CANTIDAD 0和M.Origen=“FAC”
M.NRODCTO=@pNrodcto和M.TIPODCTO=@pTipodcto';
exec sp_executesql@sql、@params、@pNrodcto、@pTipodcto、@pUsuario、@pEmpresa;
为了避免将参数直接连接到已执行的sql字符串,我将参数包装在对db\u name()
和db\u id()
的调用中。这将为无效的数据库名称返回null,但不会阻止某人引用您不希望他们引用的数据库。考虑将参数值与白名单进行比较。
参考:
不要使用不同的数据库名称动态创建查询,而是动态创建数据库连接,并从查询中省略此数据库名称。而是指定第二个表的数据库名称(Dbo.vReporteMercia\u ESP
)。我假设另一个表总是来自同一个数据库
根据连接类型,您必须在连接字符串中动态设置Initial Catalog=
或Database=
SELECT ...
FROM
dbo.MVTRADE M WITH(NOLOCK) -- Database from dynamic connection
INNER JOIN
MyNonDynamicDatabase.dbo.vReporteMercia_ESP P ON P.PRODUCTO = M.PRODUCTO
...
与其使用不同的数据库名称动态创建查询,不如动态创建数据库连接,并从查询中省略此数据库名称。而是指定第二个表的数据库名称(Dbo.vReporteMercia\u ESP
)。我假设另一个表总是来自同一个数据库
根据连接类型,您必须在连接字符串中动态设置Initial Catalog=
或Database=
SELECT ...
FROM
dbo.MVTRADE M WITH(NOLOCK) -- Database from dynamic connection
INNER JOIN
MyNonDynamicDatabase.dbo.vReporteMercia_ESP P ON P.PRODUCTO = M.PRODUCTO
...
不要害怕在您的查询中添加一些回车和其他空格,以便它们清晰可见。读起来很痛苦。注意NOLOCK提示…它不仅仅是脏的阅读。常规T-SQL查询中的表名和列名不能参数化——如果您真的必须参数化,那么除了使用动态SQL之外,别无其他方法——尽管它有很多缺点和缺点issues@SeanLange谢谢你的推荐。我很感激您在查询中添加一些回车和其他空格,以便它们清晰易读。读起来很痛苦。注意NOLOCK提示…它不仅仅是脏的阅读。常规T-SQL查询中的表名和列名不能参数化——如果您真的必须参数化,那么除了使用动态SQL之外,别无其他方法——尽管它有很多缺点和缺点issues@SeanLange谢谢你的推荐。我很感激