Concatenate the database name in a SQL multipart identifier

末鹿安然 提交于 2019-12-04 06:23:57

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!