使用 Excel 数据库连接时的 SQL IN 语法

使用 Excel 数据库连接时的 SQL IN 语法

我正在使用多个 Excel 文件连接到 SQL Server 数据库,获取 Excel 表单元格中指定的特定产品编号的销售数据。

这是通过在 SQL 连接中定义参数来设置的

SELECT ProductCode, Sales
    WHERE ProductCode = ?

并在工作表中包含产品编号的单元格中指定。这很好用,但是我现在想一次提取多个产品的销售额。我在 Excel 中自动创建了一个逗号分隔的列表,但尝试使用它作为参数总是会导致此错误消息:

语法错误信息截图

我正在输入 SQL 代码,因为WHERE ProductCode IN ?理想情况下我希望参数单元格能够在 Excel 中动态更改,但我也尝试过WHERE ProductCode IN (1,2,3)WHERE ProductCode IN (N'1', N'2', N'3')和其他各种不同的语法。我还在 Excel 生成的产品编号列表中复制了此语法。(本例中的 1、2 和 3 是示例产品代码)。

我可以使用的一些替代方法是使用WHERE ProductCode=? OR ProductCode=? OR ProductCode=?等并将每个代码指定为单独的参数,但可能至少有 200 个产品代码,因此这远非理想,这也意味着每当需要获取的代码数量超过我设置为参数的单元格数量时,我都必须手动编辑 SQL 代码,而且大多数同事在我不在的情况下也不具备执行此操作的 SQL 知识。

可能我只是使用了错误的语法,但希望有人能指出我可能出错的地方。无论我选择哪种格式,错误消息都是相同的,所以我无法弄清楚问题可能是什么。

这是可以正常工作的完整查询:

SELECT
PRODUCT.ProductCode
,SALES.Quantity
,SALES.Date

FROM
  SALES
INNER JOIN PRODUCT
    ON SALES.ProductCode = PRODUCT.ProductCode
WHERE
  ((SALES.Date >=? AND SALES.Date<=?)
AND PRODUCT.ProductCode=?

答案1

2017 年及以后的代码草案

-- output list
SELECT PRODUCT.ProductCode
      ,SALES.Quantity
      ,SALES.Date

-- data sources
FROM       SALES
INNER JOIN PRODUCT
        ON SALES.ProductCode = PRODUCT.ProductCode
-- including CSV codes list transferred as single parameter and parsed to rowset
INNER JOIN (SELECT value
            FROM STRING_SPLIT(?,',')) AS parameters(productCode)
        ON PRODUCT.ProductCode = parameters.productCode

-- filtering by date range transferred as a pair of parameters
WHERE (SALES.Date >=? AND SALES.Date<=?)

简化小提琴(按SALES.Date已移除筛选)

它似乎是 SQL Server 2014,兼容级别 120。

适用于SQL Server 2014的解决方案:

-- output list
SELECT PRODUCT.ProductCode
      ,SALES.Quantity
      ,SALES.Date

-- data sources
FROM       SALES
INNER JOIN PRODUCT
        ON SALES.ProductCode = PRODUCT.ProductCode
-- including CSV codes list transferred as single parameter and parsed to rowset
INNER JOIN (SELECT b.n.value('@n', 'int')
            FROM (SELECT CAST('<item n = "' + REPLACE(?, ',', '"/><item n="') + '"/>' AS XML)) a(x) 
            CROSS APPLY a.x.nodes('item') b(n)) AS parameters(productCode)
        ON PRODUCT.ProductCode = parameters.productCode

-- filtering by date range transferred as a pair of parameters
WHERE (SALES.Date >=? AND SALES.Date<=?)

简化小提琴(按SALES.Date已移除筛选)

相关内容