【问题标题】:Replace SQL query parameter in a Excel power query替换 Excel 电源查询中的 SQL 查询参数
【发布时间】:2020-01-26 09:19:21
【问题描述】:

我有一个工作簿,我在其中使用 SQL 查询的固定参数值从 SQL Server 获取数据。

我想制作另一张表,并从单元格值中获取 SQL 查询的参数。

在这方面我没有找到任何东西。

我还想在另一张表中的单元格值更改后立即刷新数据。

【问题讨论】:

  • 当我第一次寻找同样的问题时,我也很难找到答案。我认为通常更建议尽可能在没有变量限制的情况下运行数据查询,然后在 PowerQuery 中限制数据。有时我从 PQ 收到关于使用这种设置刷新查询的警告.....

标签: excel vba powerquery excel-2016


【解决方案1】:

为此,您需要设置三个不同的部分:

1) Excel 工作表中的参数表

2) PowerQuery 中高级编辑器的更改

3) 当参数表中的任何单元格更改时刷新 PQ 的宏


1) Excel 表格

您可以看到我包含了一个名为 param 的列,可以包含一个参数名称,以帮助明确哪个参数是哪个。


2) PQ 高级编辑器

let
    ParamTable = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    Param = "'" & Text.From(ParamTable[value]{0}) & "'",
    Source = Sql.Database("IP Address", "Database Name", [Query="Select * from weeks#(lf)where date >= '2018-01-01' and date < " &Param])
in
    Source

等效替代:(SQL 查询中使用的变量位置的差异。)

let
    ParamTable = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    Param = "'" & Text.From(ParamTable[value]{0}) & "'",
    Source = Sql.Database("IP Address", "Database Name", [Query="Select * from weeks#(lf)where date < " &Param & " and date >= '2018-01-01'"])
in
    Source

替代变量类型:(如果处理数字,则不需要字符串标记'

let
    ParamTable = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    Param = Text.From(ParamTable[value]{0}),
    Source = Sql.Database("IP Address", "Database Name", [Query="Select * from weeks#(lf)where cnt < " &Param & " and date >= '2018-01-01'"])
in
    Source

说明:

将参数表拉入 PQ 查询 (ParamTable = Excel.CurrentWorkbook(){[Name="Table1"]}[Content]) 后,可以通过列名 [value] 访问列,通过零索引号 {0} 访问行。因为我正在提取日期值。我需要将它转换为可以插入到 SQL 查询中的字符串值——因此 Text.From() 和附加的 ' 到末尾(SQL 用单个 ' 而不是双 ")

由于我将变量命名为Param,为了在字符串中使用它,我将&amp;Param 替换为原来存在的值。


2.1 Power Query 的 Value.NativeQuery

let
    ParamTable = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    Param = ParamTable[value]{0},
    Source = Value.NativeQuery(Sql.Database("IP Address", "Database Name"), "Select * from weeks where date < @dateSel and date >= '2018-01-01'",[dateSel = Param])
in
    Source

替代格式:

let
    ParamTable = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    Param = ParamTable[value]{0},
    Source = Sql.Database("IP Address", "Database Name"),
    Data = Value.NativeQuery(Source, "

Select * from weeks
where date < @dateSel and date >= '2018-01-01'

",[dateSel = Param])
in
    Source

注意事项:

使用Value.NativeQuery() 时,您可以直接将日期或日期时间值作为变量传递,而无需包含单个撇号。

有时将数据检索拆分为Source 步骤和NativeQuery 步骤有助于解决 PQ 偶发的防火墙问题。


3) 宏

这适用于简单检查表中是否有任何更改,然后运行刷新。您需要确保将其放置在正确的模块中。您需要更改的项目是:

  • Sheet1 是带参数表的工作表的代号。
  • "Table"是参数表的名称
  • "Query - Query1" 是要刷新的连接的名称

注意: Query1 是查询的名称。连接的默认名称通常是Query - & 查询名称

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Sheet1.ListObjects("Table1").DataBodyRange) Is Nothing Then
        ThisWorkbook.Connections("Query - Query1").Refresh
    End If
End Sub

【讨论】:

  • 您知道如何进入通用查询编辑器吗?在那里,转到“查看”选项卡,然后您应该会看到右侧第二个“高级编辑器”按钮。最右边的按钮是“Query Dependencies”按钮,也是半有用的。
  • 我在高级编辑器中粘贴电源查询时收到cyclic reference was encountered during evaluation 错误。你能帮忙吗?
  • 我可以试试。你能告诉我你在高级编辑器中的代码吗?另外,只是澄清一下,对于第 2 部分),我发布的内容实际上只是添加了 param 行和适当的变量替换后的外观示例。
  • 当然。 let Client_UID = "'" &amp; Text.From(Table1[value]{0}) &amp; "'", Year = "'" &amp; Text.From(Table1[value]{1}) &amp; "'", Period = "'" &amp; Text.From(Table1[value]{2}) &amp; "'", Source = Sql.Database("0.0.0.0", "TestDB", [Query="EXEC [sp_sprocname] @Client_UID = " &amp;Client_UID &amp; ", @Year = " &amp;Year &amp; ", @Period = " &amp;Period &amp; ", @Trans = '123'"]) in Source
  • 首先,我只想指出 @Year 不应该是 SQL 字符串(即 SQL 需要整数或双精度),您应该将 Year = "'" &amp; Text.From(Table1[value]{1}) &amp; "'" 更改为 Year = Text.From(Table1[value]{1}) , 与任何其他值相同,SQL 不期望字符串。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-08
  • 2016-12-17
  • 1970-01-01
  • 2021-12-26
  • 1970-01-01
相关资源
最近更新 更多