【问题标题】:SQL/C# - Apply a function to columns within a SQL querySQL/C# - 将函数应用于 SQL 查询中的列
【发布时间】:2018-06-21 09:34:00
【问题描述】:

有没有办法解析给定的 SQL SELECT 查询并用函数调用包装每一列,例如dbo.Foo(column_name) 在运行 SQL 查询之前?

我们已经研究过在列名上使用正则表达式类型“replace”,但是,我们似乎无法解释所有可以编写 SQL 查询的方式。

SQL 查询的一个示例是;

SELECT 
    [ColumnA]
  , [ColumnB]
  , [ColumnC] AS [Column C]
  , CAST([ColumnD] AS VARCHAR(11)) AS [Bar]
  , DATEPART([yyyy], GETDATE()) - DATEPART([yyyy], [ColumnD]) AS [Diff]
  , [ColumnE]
FROM [MyTable]
WHERE LEN([ColumnE]) > 0
ORDER BY 
    [ColumnA]
  , DATEPART([yyyy], [ColumnD]) - DATEPART([yyyy], GETDATE());

我们需要的结果是;

SELECT 
    [dbo].[Foo]([ColumnA])
  , [dbo].[Foo]([ColumnB])
  , [dbo].[Foo]([ColumnC]) AS [Column C]
  , CAST([dbo].[Foo]([ColumnD]) AS VARCHAR(11)) AS [Bar]
  , DATEPART([yyyy], GETDATE()) - DATEPART([yyyy], [dbo].[Foo]([ColumnD])) AS [Diff]
  , [dbo].[Foo]([ColumnE])
FROM [MyTable]
WHERE LEN([dbo].[Foo]([ColumnE])) > 0
ORDER BY 
    [dbo].[Foo]([ColumnA])
  , DATEPART([yyyy], [dbo].[Foo]([ColumnD])) - DATEPART([yyyy], GETDATE());

上述任何或所有列可能需要对其调用的函数(包括在WHEREORDER BY 中使用的列),这就是我们需要查询范围解决方案的原因。

我们有很多像上面这样的预先编写的查询需要更新,这就是手动更新很困难的原因。

上面的例子显示了一些结果列可能会被计算,而一些只是被重命名。大多数也由连接组成,有些包含我为了本示例的目的而省略的 case 语句。

另一个需要考虑的情况是表名别名,例如SELECT t1.ColumnA, t2.ColumnF

解决此问题的 SQL 或 C# 解决方案都是理想的。

【问题讨论】:

标签: c# sql .net sql-server sql-function


【解决方案1】:

您可以替换语句而不是替换每列的每次出现...

FROM MyTable

...使用包含函数调用的所有现有列的子选择:

FROM (
    SELECT dbo.Foo(ColumnA) AS ColumnA, dbo.Foo(ColumnB) AS ColumnB,
        dbo.Foo(ColumnC) AS ColumnC --etc.
    FROM MyTable
) AS MyTable

查询的其余部分可以保持不变。在表别名的情况下,您只需将AS Table1 替换为AS t1

您应该考虑的另一个选择是在您的数据库中创建本质上是子选择的视图。结合命名约定,您可以轻松地将 FROM(和 JOIN)语句中的出现替换为视图名称:

FROM MyTable_Foo AS t1

如果您想替换您将要使用的所有个查询,请考虑重命名这些表并创建名称与旧表类似的视图。


更一般的说明:您应该重新考虑解决潜在问题的方法,因为您在这里所做的事情会带走 SQL 的大部分功能。最糟糕的是,一旦您在所有列上调用该函数,您将无法使用这些列上的索引,这可能意味着对数据库性能的严重影响。

【讨论】:

  • 这种方法的另一个优点是它不会改变输出。在您的示例中,您有 ColumnE 并将其更改为 dbo.Foo(ColumneE),这意味着在原始输出中您将有一个名为 ColumnE 的列,但在您修改后的脚本中,该列不再定义名称,因此将显示为 @ 987654331@.
猜你喜欢
  • 2016-08-07
  • 2012-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-28
  • 2014-06-11
  • 2016-02-26
  • 1970-01-01
相关资源
最近更新 更多