我有以下元数据,它提供有关数据库中表层次结构的信息:
通过循环,我可以构造以下sql语句。还有另一种无需循环的整洁方法吗?
SELECT
SubClassCode,
ClassCode,
DeptCode,
DivisionCode INTO tempTable
FROM tblSBDivisionMaster T1
JOIN tblSBDepartmentMaster T2
ON T2.ParentID = T1.DivisionID
JOIN tblSBClassMaster T3
ON T3.ParentID = T2.DeptID
JOIN tblSBSubClassMaster T4
ON T4.ParentID = T3.ClassID
带有循环示例:
declare @merchandiseHierCount as int ,@nextrowscount as int,@join as varchar(1000),@firstTable as varchar(200),@codeColumns as varchar(1000)
SELECT
@codeColumns = COALESCE(@codeColumns + ',', '') + MasterCodeColumn
FROM tblsbhierarchy
WHERE HierarchyType = 1
ORDER BY HierLevel;
SET @merchandiseHierCount = (SELECT
COUNT(*)
FROM tblsbhierarchy
WHERE HierarchyType = 1)
select @firstTable = MasterTableName FROM tblsbhierarchy
WHERE HierarchyType = 1 and HierLevel =1
set @nextrowscount =1
WHILE (@nextrowscount <= @merchandiseHierCount)
begin
declare @tableName as varchar(100),@heir as varchar(20),@IdColumn as varchar(100)
select @tableName = MasterTableName,@heir= HierLevel,@IdColumn = MasterKeyColumn from tblsbhierarchy where HierLevel = @nextrowscount and HierarchyType=1
if @nextrowscount >1
begin
SET @join = (SELECT
CONCAT(@join,' join ' + @tableName + ' T' + @heir + ' on '
+' T'+ @heir + '.' + @IdColumn + ' = T' + cast((@heir-1) as VARCHAR) + '.ParentId'))
end
set @nextrowscount = @nextrowscount+1
end
set @join = 'Select '+ @codeColumns+ ' into temptable From ' + @firstTable +' T1 ' + @join
select @join
最终查询,@ Squirrel对查询进行了一些修改。我请求的查询有一个小错误。所以我对最终结果做了更正。
declare @select nvarchar(max),
@from nvarchar(max),
@sql nvarchar(max)
;
WITH tbl
AS
(SELECT
HierLevel,MasterTableName,MasterKeyColumn,MasterCodeColumn
,tbl = 'T' + CONVERT(VARCHAR(5), HierLevel)
,parent = 'T' + CONVERT(VARCHAR(5), LAG(HierLevel) OVER (ORDER BY HierLevel))
,parentId = lag(MasterKeyColumn) over( ORDER by HierLevel)
FROM tblsbhierarchy
WHERE HierarchyType = 1)
SELECT
@select = ISNULL(@select + ', ', 'SELECT ')
+ tbl + '.' + MasterCodeColumn
,@from = ISNULL(@from, '')
+
CASE
WHEN HierLevel = 1 THEN 'INTO temptable' + CHAR(13)
ELSE ''
END
+
CASE
WHEN HierLevel = 1 THEN 'FROM '
ELSE 'JOIN '
END
+ MasterTableName
+ ' AS ' + tbl + CHAR(13)
+
CASE
WHEN HierLevel <> 1 THEN CHAR(9) + 'ON ' + tbl + '.ParentId' + ' = ' + parent + '.'+parentId + CHAR(13)
ELSE ''
END
FROM tbl
ORDER BY HierLevel
SELECT
@sql = @select + CHAR(13) + @from
print @sql
答案 0 :(得分:1)
这将为您提供格式精美的查询。基本上,它使用字符串连接并检查HierLevel。如果level = 1或其他,则采取相应措施。 char(13)
是回车符,因此当您执行PRINT
时,会得到一个格式良好的可读查询
declare @select nvarchar(max),
@from nvarchar(max),
@sql nvarchar(max)
; with tbl as
(
select *,
tbl = 'T' + convert(varchar(5), HierLevel),
parent = 'T' + convert(varchar(5), LAG(HierLevel) OVER(ORDER BY HierLevel))
from tblsbhierarchy
where HierarchyType = 1
)
select @select = isnull(@select + ', ', 'SELECT ')
+ tbl + '.' + MasterCodeColumn,
@from = isnull(@from, '')
+ case when HierLevel = 1 then 'INTO temptable' + char(13) else '' end
+ case when HierLevel = 1 then 'FROM ' else 'JOIN ' end
+ MasterTableName
+ ' AS ' + tbl + char(13)
+ case when HierLevel <> 1
then char(9) + 'ON ' + tbl + '.' + MasterKeyColumn + ' = ' + parent + '.ParentId' + char(13)
else ''
end
from tbl
order by HierLevel
select @sql = @select + char(13) + @from
print @sql
/* RESULT
SELECT T1.DivisionCode, T2.DeptCode, T3.ClassCode, T4.SubClassCode
INTO temptable
FROM tblSBDivisionMaster AS T1
JOIN tblSBDepartmentMaster AS T2
ON T2.DeptID = T1.ParentId
JOIN tblSBClassMaster AS T3
ON T3.ClassID = T2.ParentId
JOIN tblSBSubClassMaster AS T4
ON T4.SubClassID = T3.ParentId
*/