题
我期待重构下面查询更多的东西可读和可修改的。前半部分是等同于第二,从查询的数据库的除外(表名是相同的,但。)
SELECT
Column 1 AS c1,
...
Column N AS cN
FROM
database1.dbo.Table1
UNION
SELECT
'Some String' as c1,
...
NULL as cN
FROM
database1.dbo.Table2
UNION
SELECT
Column 1 AS c1,
...
Column N AS cN
FROM
database2.dbo.Table1
UNION
SELECT
'Some String' as c1,
...
NULL as cN
FROM
database2.dbo.Table2
此查询是 DRY 和正在呼叫我被重新-written,但我不知道怎么办!
修改强>:我们不能使用LINQ和我们所希望的结果不同;我期待在做物理文件大小的查询时,不返回的结果。
修改强>:我查询过的数据库是一个专有的ERP数据库。重组它不是一个选项。
解决方案
这是相当标准的SQL模式。有时很容易像干inadvisedly转移OOP /程序代码原则SQL,但他们不一定转让的概念。
请注意,你是多么容易神交查询的整个逻辑设计,与通过子模块打猎。如果子表达式的人有一个额外的列或列对调,它会伸出。这基本上是一个相当简单的SQL语句神交作为执行单元,其中解聚,将它蒙混
当你正在调试,这是很方便的可以使用编辑器的文本高亮显示选项有选择地行使声明的部分 - 这并不在程序代码中存在的技术。 OTOH,如果他们分散到的意见等。即使热膨胀系数可以使这种不便它会导致混乱设法追踪下来所有的作品。
其他提示
我要在这里走出去的肢体,并说,根据您提供给我们的信息;
这是好,因为它会得到
一个性能尖端,我看到了蝙蝠使用UNION ALL
的UNION
代替除非您有意不重复的记录。一个简单的UNION
将消除重复这需要时间。 UNION ALL
没有做到这一点。
您可以使用动态SQL和循环重写,但我想结果会更糟糕。如果有足够的重复代码来证明动态sql的方法,那么我想这可能是合理的。
可替换地,有你认为是逻辑出所存储的程序的移动成类似LINQ?对于许多人来说,这是不是一种选择,所以我只是问。
最后要注意的:抗拒的冲动解决什么不破只是为了使它看起来更干净。如果清理将助手在维护,验证等,然后去了。
这是什么问题?太长?过于重复?
有时你会得到丑陋的SQL - 没有什么可以做的。
我看不出有什么办法把它清理干净,除非你想使用独立的意见,然后联合在一起。
我投了意见,其中征收近零不够开销(好吧,也许一个小的编译时间成本但应该是所有)。那么你的特效成为形式的东西。
SELECT * FROM database1.view1
UNION
SELECT * FROM database1.view2
UNION
SELECT * FROM database2.view1
UNION
SELECT * FROM database2.view2
我不知道如果我想任何进一步凝结,虽然我希望大多数平台不会容忍它。
在动态SQL主题 - 这里是一个样本 - 如果不知道这是任何好转。好处是,你只需要编写一次SELECT列表。
DECLARE @Select1 varchar(1000)
DECLARE @Select2 varchar(1000)
DECLARE @SQL varchar(4000)
SET @Select1 = 'SELECT
Column 1 AS c1,
...
Column N AS cN'
SET @Select2 = 'SELECT
''Some String'' as c1,
...
NULL as cN'
SET @SQL = @Select1 + ' FROM database1.dbo.Table1 '
SET @SQL = @SQL + ' UNION ' + @Select2 + ' FROM database1.dbo.Table2 '
SET @SQL = @SQL + ' UNION ' + @Select1 + ' FROM database2.dbo.Table1 '
SET @SQL = @SQL + ' UNION ' + @Select2 + ' FROM database2.dbo.Table2 '
EXEC @SQL
如果您所有的特效看起来像这样 - 你可能有一个结构问题。
。是否所有呼叫参见表2只还有一个有用的领域? (因为UNION的,最终仅具有一个列?)
我完全第二与参数化动态SQL和/或代码生成该作业持续,即使去,至于动态生成使用INFORMATION_SCHEMA
列列表中的想法。这不正是你所需要的,但它是一个开始(可能产生断的数据库和表一表):
DECLARE @template AS varchar(MAX)
SET @template = 'SELECT {@column_list} FROM {@database_name}.dbo.{@table_name}'
DECLARE @column_list AS varchar(MAX)
SELECT @column_list = COALESCE(@column_list + ',', '') + COLUMN_NAME
FROM database1.dbo.INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @table_name
ORDER BY ORDINAL_POSITION
DECLARE @sql AS varchar(MAX)
SET @sql = @template
SET @sql = REPLACE(@sql, '{@column_list}', @column_list)
SET @sql = REPLACE(@sql, '{@database_name}', @database_name)
SET @sql = REPLACE(@sql, '{@table_name}', @table_name)
根据行数返回的,可以使用所有与它周围的选择不同的查询选择UNION最好是。 我以前见过类似的问题,有两个不同的风格不同的执行计划
SELECT DISTINCT subquery.c1, subquery.cN FROM ( SELECT Column 1 AS c1, Column N AS cN FROM database1.dbo.Table1 UNION ALL SELECT 'Some String' as c1, NULL as cN FROM database1.dbo.Table2 UNION ALL SELECT Column 1 AS c1, Column N AS cN FROM database2.dbo.Table1 UNION ALL SELECT 'Some String' as c1, NULL as cN FROM database2.dbo.Table2 ) subquery