問題相當廣泛,請與我聯繫。我有一個具有以下結構的單映射表:查詢以選擇下一列,如果當前列不返回任何行
這種特殊的表中生成一個層次結構的方法中使用。表格中列的順序和位置表示層次結構的順序(組織,類別,大陸,國家等)。此層次結構中的每個實體都有一個關聯表,其中有關聯的Id
和Name
。例如,有一個Country
表,CountryId
和CountryName
。請注意,由於MappingTable的值都是可以爲空的,所以有沒有外鍵約束。
我想生成一個過程,將執行以下操作:根據提供的條件
,層次結構中檢索下一個實體的值。例如,如果給出OrganizationId
和CategoryId
,則需要檢索滿足所述條件的值ContinentId
。
而且,如果ContinentId
的值是NULL
,則需要檢索CountryId
的值。在這裏,給定條件OrganizationId = 1 and CategoryId = 1
該過程應該返回RegionId
的列表。
除了檢索RegionId
之外,還應該從Region
表中檢索相應的RegionName
。
到目前爲止,該過程看起來像這樣 - 只是在這裏解釋一些事情。
ALTER PROCEDURE [dbo].[GetHierarchy]
(
@MappingTableName VARCHAR(30),
@Position VARCHAR(5),
-- Given in the form of Key-value pairs 'OrganizationId:1,CategoryId:1'
@InputData VARCHAR(MAX),
@Separator CHAR(1),
@KeyValueSeperator CHAR(1)
)
AS
BEGIN
DECLARE @Sql NVARCHAR(MAX)
DECLARE @Result NVARCHAR(MAX)
DECLARE @Sql1 NVARCHAR(MAX);
DECLARE @TableName NVARCHAR(30)
DECLARE @Exists bit
SELECT @TableName = COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = @MappingTableName AND ORDINAL_POSITION = @position
SET @TableName = SUBSTRING(@TableName,0,LEN(@TableName) - 1)
-- Returns a dynamic query like "SELECT ContinentId from Continent WHERE OrganizationId = 1 and CategoryId = 1".
SELECT @Sql = [dbo].[KeyValuePairs](@TableName, @InputData, @Separator, @KeyValueSeperator)
SET @Sql1 = N'SET @Exists = CASE WHEN EXISTS(' + @Sql + N' AND ' + @TableName + N'Id IS NOT NULL) THEN 1 ELSE 0 END'
PRINT @Sql
EXEC sp_executesql @Sql1,
N'@Exists bit OUTPUT',
@Exists = @Exists OUTPUT
IF(@Exists = 1)
BEGIN
SET @Sql1 = 'SELECT ' + @TableName + 'Id, ' + @TableName + 'Name FROM '+ @TableName+' WHERE ' + @TableName +'Id IN (' + @Sql + ')';
PRINT @Sql1
EXECUTE sp_executesql @SQL1
END
ELSE
BEGIN
--PRINT 'NOT EXISTS'
DECLARE @nextPosition INT
SELECT @nextPosition = CAST(@position AS INT)
SET @nextPosition = @nextPosition + 1
SET @Position = CONVERT(VARCHAR(5), CAST(@position AS INT))
EXEC [dbo].[GetHierarchy] @MappingTableName, @Position, @InputData, @Separator, @KeyValueSeperator
END
END
這個程序的邏輯是這樣的,我在一個特定的位置(基於此,它是Continent
的條件)獲得列的名稱和基於生成動態查詢,以獲得下一列的值在輸入條件的條件下(我正在使用一個單獨的函數爲我做這件事)。 一旦檢索,我運行查詢來檢查它是否返回任何行。如果查詢返回行,則我從Continent
表中檢索相應的ContinentName
。如果沒有行返回,我遞歸調用該過程,下一個位置作爲輸入。
在事物的商業方面,它似乎是一個兩步過程。但是,作爲一個程序,它是相當複雜,廣泛的 - 更不用說遞歸了。有沒有更簡單的方法來做到這一點?我對CTE不熟悉 - CTE能否實現相同的邏輯?
這很類似於在這裏問:Working with a dynamic hierarchy SQL Server