我正在编写存储过程,并且我试图在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
我直接从存储过程中获取变量
@pEmpresa AS char(20)
我知道我可以IF
喜欢
IF (@pEmpresa = 'John Doe')
BEGIN
--..... and the query here
END
是否可以使用变量连接数据库名称?怎么样?或者我应该使用IF
?
答案 0 :(得分:4)
你必须使用动态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;
为了避免将参数直接连接到已执行的sql字符串,我将参数包装在对db_name()
和db_id()
的调用中。对于无效的数据库名称,这将返回null,但不会阻止某人引用您不希望它们访问的数据库。考虑将参数值与白名单进行比较。
参考:
答案 1 :(得分:1)
不是使用不同的数据库名称动态创建查询,而是动态创建数据库连接,并从查询中省略此数据库名称。而是指定第二个表(Dbo.vReporteMercia_ESP
)的数据库名称。我假设另一个表总是来自同一个数据库。
根据连接类型,您必须在连接字符串中动态设置Initial Catalog=<database name>
或Database=<database name>
。
SELECT ...
FROM
dbo.MVTRADE M WITH(NOLOCK) -- Database from dynamic connection
INNER JOIN
MyNonDynamicDatabase.dbo.vReporteMercia_ESP P ON P.PRODUCTO = M.PRODUCTO
...