使用Transact sql的临时表

时间:2016-07-27 11:17:24

标签: sql sql-server tsql linked-server

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

 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. 将创建临时表并将其添加到数据库中
  2. @@query@query未被识别为有效参数
  3. 那么我该如何解决这些问题呢?

1 个答案:

答案 0 :(得分:3)

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

  

OPENQUERY不接受其参数的变量。

所以你必须制作一个动态查询,或者在你的cace中,只需将查询文本移到OPENQUERY

OPENQUERY(SAB, 'Query text comes here') 

要传递'参数',您可以按照此处所述的说明操作:https://support.microsoft.com/en-us/kb/314520

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

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

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

以下是一些规则:

  • 为QueryText中的每个返回列添加别名(SQL Server无法处理无用的列),
  • 仅返回必要的列(以减少网络流量以及远程和本地服务器的负载)
  • 您必须在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注入是开放的。

如果可以,请将数据保存在永久表中(例如使用SSIS)并使用同步数据。