在包含逗号的SQL Where子句中使用变量

时间:2017-07-25 22:11:55

标签: sql-server sql-server-2008 openquery

我有一个SQL Server 2008中的表。该表有一个名为CC_TERMID的字段,它是一个数字字段。我有一个数据位于oracle服务器上,我想在其中查找当前的TermID,并且我希望将其用作针对我的SQL表的变量。我很确定我的错误是数据类型不匹配,但我无法弄清楚如何存储变量的数据。

这是我使用openquery创建的变量,用于从Oracle获取我想要的数据:

    DECLARE @TERMS nvarchar(50)
    SET @TERMS = (SELECT * FROM OPENQUERY(POWERSCHOOL,
    '
    SELECT TO_NUMBER(LISTAGG(ID, '','') WITHIN GROUP (ORDER BY SCHOOLID))
    FROM TERMS
    WHERE SYSDATE + (SELECT FIRSTDAY - SYSDATE
                     FROM TERMS
                     WHERE ISYEARREC = 1 AND YEARID = (SELECT MAX(SUBSTR(TERMID, 1,2))
                                                       FROM CC) AND SCHOOLID = 51) BETWEEN FIRSTDAY AND LASTDAY AND SCHOOLID = 51
   '))

返回数据,如2700,2701,2703,2704

现在我想在查询中对我的SQL表使用该变量,如下所示:

    SELECT TCH_EMAIL_ADDR, TCH_LAST_NAME, TCH_FIRST_NAME, CC_TERMID
    FROM ZPS_CCRAW
    WHERE CC_TERMID IN (@TERMS)

当然我收到错误:"将数据类型nvarchar转换为数字"时出错。我试图将CC_TERMID CAST / CONVERT转换为nvarchar,如下所示:

    SELECT TCH_EMAIL_ADDR, TCH_LAST_NAME, TCH_FIRST_NAME, CC_TERMID
    FROM ZPS_CCRAW
    WHERE CAST(CC_TERMID AS NVARCHAR(50)) IN (@TERMS)

但我没有得到任何结果。如果我删除@TERMS并输入2700,2701,2703,2704,那么我将按预期返回数据。

在撰写陈述时,我离专家不远。我知道这足以让我陷入这样的麻烦,但还不足以知道如何摆脱它。任何人都可以帮助我实现我想要的目标吗?

2 个答案:

答案 0 :(得分:0)

你必须原谅我,我对Oracle并不擅长,所以我对你的子查询做出的改变可能不会很有效。但基本上这个想法是,不要序列化列表。只需将其保留为设定数据即可。

  DECLARE @TERMS table (Id int)

  insert into @TERMS (Id)
  SELECT ID FROM OPENQUERY
  (
      POWERSCHOOL,
      'SELECT DISTINCT ID 
       FROM TERMS
       WHERE SYSDATE + (SELECT FIRSTDAY - SYSDATE
                        FROM TERMS
                        WHERE ISYEARREC = 1 AND YEARID = (SELECT MAX(SUBSTR(TERMID, 1,2))
                                                          FROM CC) AND SCHOOLID = 51) BETWEEN FIRSTDAY AND LASTDAY AND SCHOOLID = 51'
  )

然后将您的后续查询更改为以下内容:

 SELECT TCH_EMAIL_ADDR, TCH_LAST_NAME, TCH_FIRST_NAME, CC_TERMID
 FROM ZPS_CCRAW
 WHERE CC_TERMID IN (select Id @TERMS)

 SELECT TCH_EMAIL_ADDR, TCH_LAST_NAME, TCH_FIRST_NAME, CC_TERMID
 FROM ZPS_CCRAW a
 INNER JOIN @TERMS b
      on a.CC_TERMID = b.Id

注意,如果您愿意,可以直接从OPENQUERY执行相同操作,而不是将它们转储到表变量中。

基本上发生的事情是你有一张看起来像......的桌子。

... CC_TERMID
... 2700
... 2701
... 2703
... 2704 

...而您现在正在说"给我所有CC_TERMID等于字符串文字的行"2700,2701,2703,2704"

答案 1 :(得分:0)

您的Oracle查询没问题。这是SQL Server解释语句的方式。自从我使用SQL Server以来已经有一段时间,但我认为你不能以这种方式使用变量。我会使用动态查询,因此@terms将被解释为值列表而不是字符串。