问题
I'm writing a stored procedure and I'm trying to concatenate the database name in the multipart identifier after FROM without success. This is one way that I tried but it didn't work
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
I get the variable directly from the stored procedure
@pEmpresa AS char(20)
I know that I can do an IF like
IF (@pEmpresa = 'John Doe')
BEGIN
--..... and the query here
END
Is it possible to concatenate the database name using the variable? How? Or should I just use the IF?
回答1:
You would have to use dynamic sql to do something like that.
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;
To avoid directly concatenating a parameter to an executed sql string, I wrapped the parameter in calls to db_name() and db_id(). This would return null for an invalid database name, but wouldn't stop someone from referencing a database you do not want them to. Consider comparing the parameter value against a white list.
Reference:
- The curse and blessings of dynamic SQL - Erland Sommarskog
- sp_executesql
回答2:
Instead of creating the query dynamically with different database names, create the database connection dynamically and omit this database name from the query. Instead specify the database name of the second table (Dbo.vReporteMercia_ESP). I assume that the other table is always from the same database.
Depending on the connection type, you would have to set Initial Catalog=<database name> or Database=<database name> dynamically in the connection string.
SELECT ...
FROM
dbo.MVTRADE M WITH(NOLOCK) -- Database from dynamic connection
INNER JOIN
MyNonDynamicDatabase.dbo.vReporteMercia_ESP P ON P.PRODUCTO = M.PRODUCTO
...
来源:https://stackoverflow.com/questions/43079674/concatenate-the-database-name-in-a-sql-multipart-identifier