临时 table 使用交易 sql

Temporary table using Transact sql

我是 T-SQL 的初学者,我有这个问题:我想使用 临时 table 而不是创建它,所以我写了这个存储过程:

 create PROCEDURE [dbo].[proc_Affaires_By_Client] 
    @clt_nom varchar(255) ,
    @cmd_numero varchar(10),
    @etap_cmd_libelle varchar(50),
    @typ_cmd_libelle varchar(50)
AS 
Begin
    DECLARE @temp_tbl_proc TABLE (cmd_code_pk int NOT NULL,
                                  clt_nom varchar(255) NOT NULL,
                                  cmd_nom varchar(100) NOT NULL,
                                  etap_cmd_libelle varchar(50) NULL,
                                  DateAncienTS DateTime NULL,
                                  DateTecentTS DateTime NULL,
                                  TotalHeure numeric(3,2) not null,
                                  TotalHeurePerid numeric(3,2) not null
                                 );


    INSERT INTO @temp_tbl_proc(cmd_code_pk, clt_nom, cmd_numero, cmd_nom, etap_cmd_libelle, typ_cmd_libelle, DateAncienTS, DateTecentTS, TotalHeure, TotalHeurePerid) 
        SELECT        
            ISNULL(cmd_code_pk, 1) AS cmd_code_pk, clt_nom, cmd_numero, 
            cmd_nom, etap_cmd_libelle, typ_cmd_libelle, 
            CONVERT(datetime, '01/01/1900', 103) AS DateAncienTS, 
            CONVERT(datetime, '01/01/1900', 103) AS DateTecentTS, 
            -1.00 AS TotalHeure, -1.00 AS TotalHeurePerid
        FROM    
            OPENQUERY(SAB, 'SELECT c.cmd_code_pk, cl.clt_nom, c.cmd_numero, c.cmd_nom,et.etap_cmd_libelle,ty.typ_cmd_libelle FROM commande c,client cl,etape_commande et, type_commande ty where cl.clt_code_pk=c.cmd_clt_fk and c.cmd_etap_cmd_fk = et.etap_cmd_code_pk and c.cmd_typ_cmd_fk = ty.typ_cmd_code_pk' ) 

    SELECT * 
    FROM @temp_tbl_proc 
    ORDER BY cmd_nom;
END

问题是:

  1. 临时 table 将被创建并添加到数据库中
  2. @@query@query 未被识别为有效参数

那么我该如何解决这些问题呢?

来自https://msdn.microsoft.com/en-us/library/ms188427(v=sql.110).aspx

OPENQUERY does not accept variables for its arguments.

所以你必须设计一个动态查询,或者在你的情况下,只需将查询文本移动到 OPENQUERY

OPENQUERY(SAB, 'Query text comes here') 

要通过 'parameters',您可以按照此处描述的说明进行操作:https://support.microsoft.com/en-us/kb/314520

本质上,您必须制作一个动态查询并将其作为动态查询文本执行。

您可以在查询中使用 OPENQUERY() table:

SELECT * FROM OPENQUERY(LinkedServer, 'QueryText') AS R;

以下是一些要遵循的规则:

  • 为 QueryText 中的每个返回列添加别名(SQL 服务器无法处理匿名列),
  • Return只有必要的列(以减少网络流量和远程和本地服务器的负载)
  • 您必须在 FROM 子句中为 OPENQUERY 表达式添加别名。

所以,一个简单的例子:

DECLARE @localCache TABLE (id INT, col1 VARCHAR(MAX));

INSERT INTO @localCache (id, col1)
SELECT
  id, col1
FROM
  OPENQUERY(LinkedServer, '
    SELECT X.id AS id, Y.col AS col1
    FROM X INNER JOIN Y ON X.id = Y.x_id
  ') src

当您必须将参数传递给远程查询时,这可能会很棘手,因为您必须创建动态查询。动态查询在不同的上下文中执行,因此原始SP的变量不可用。

DECLARE @myFilter NVARCHAR(32) = 'foo'

DECLARE @dymanicQuery NVARCHAR(MAX) = N'
  INSERT INTO @localCache (id, col1)
    SELECT
      id, col1
    FROM
      OPENQUERY(LinkedServer, ''
        SELECT X.id AS id, Y.col AS col1
        FROM X INNER JOIN Y ON X.id = Y.x_id
        WHERE Y.col2 = ''''' + @myFilter + '''''
      '') src
';

DECLARE @remoteData TABLE (id INT, col1 VARCHAR(MAX));

INSERT INTO @remoteData (id, col1)
EXEC sp_executesql
  @stmt = @dymanicQuery

请注意,这可能是危险的,并且在这种形式下它可以用于 sql 注射。

如果可以,请将数据永久同步table(例如使用 SSIS)并使用同步数据。