Tsql 处理游标中结构未知的行
我不熟悉使用游标在一组行中循环。但到目前为止,我已经事先知道我将要阅读哪些专栏 例如Tsql 处理游标中结构未知的行,tsql,cursor,Tsql,Cursor,我不熟悉使用游标在一组行中循环。但到目前为止,我已经事先知道我将要阅读哪些专栏 例如 但是我将要读入键/值表的表没有特定的结构,我应该能够一次处理一行。如何使用嵌套游标循环访问所获取行的所有列,并根据它们的类型和名称对它们进行处理?TSQL游标并非真正用于从结构未知的表中读取数据。我能想到的两种实现这一目标的可能性是: 首先从信息架构视图中读取未知表的列名(请参阅)。然后使用动态SQL创建游标 如果您只是想将任何列作为大字符串值,还可以尝试使用简单的SELECT*FROM TABLE_NAME
但是我将要读入键/值表的表没有特定的结构,我应该能够一次处理一行。如何使用嵌套游标循环访问所获取行的所有列,并根据它们的类型和名称对它们进行处理?TSQL游标并非真正用于从结构未知的表中读取数据。我能想到的两种实现这一目标的可能性是:
- 首先从信息架构视图中读取未知表的列名(请参阅)。然后使用动态SQL创建游标
- 如果您只是想将任何列作为大字符串值,还可以尝试使用简单的
,并进一步处理检索到的数据以满足您的需要(请参阅)SELECT*FROM TABLE_NAME FOR XML AUTO
- 首先从信息架构视图中读取未知表的列名(请参阅)。然后使用动态SQL创建游标
- 如果您只是想将任何列作为大字符串值,还可以尝试使用简单的
,并进一步处理检索到的数据以满足您的需要(请参阅)SELECT*FROM TABLE_NAME FOR XML AUTO
SELECT
转换为XML,并使用强大的功能处理通用结构。我不建议这样做,但可能值得一试:
CREATE PROCEDURE dbo.Get_EAV_FROM_SELECT
(
@SELECT NVARCHAR(MAX)
)
AS
BEGIN
DECLARE @tmptbl TABLE(TheContent XML);
DECLARE @cmd NVARCHAR(MAX)= N'SELECT (' + @SELECT + N' FOR XML RAW, ELEMENTS XSINIL);';
INSERT INTO @tmptbl EXEC(@cmd);
SELECT r.value('*[1]/text()[1]','nvarchar(max)') AS RowID
,c.value('local-name(.)','nvarchar(max)') AS ColumnKey
,c.value('text()[1]','nvarchar(max)') AS ColumnValue
FROM @tmptbl t
CROSS APPLY t.TheContent.nodes('/row') A(r)
CROSS APPLY A.r.nodes('*[position()>1]') B(c)
END;
GO
EXEC Get_EAV_FROM_SELECT @SELECT='SELECT TOP 10 o.object_id,o.* FROM sys.objects o';
GO
--Clean-Up for test purpose
DROP PROCEDURE Get_EAV_FROM_SELECT;
简言之,这个想法
- select作为字符串传递到过程中。使用SP,我们动态创建一条语句并从中创建XML李>
- 第一列被认为是行的ID,如果不是(如在
中),我们可以编写SELECT并以这种方式强制它sys.objects
- 内部
将读取每一行并返回一个经典的EAV列表SELECT
SELECT
转换为XML,并使用强大的功能处理通用结构。我不建议这样做,但可能值得一试:
CREATE PROCEDURE dbo.Get_EAV_FROM_SELECT
(
@SELECT NVARCHAR(MAX)
)
AS
BEGIN
DECLARE @tmptbl TABLE(TheContent XML);
DECLARE @cmd NVARCHAR(MAX)= N'SELECT (' + @SELECT + N' FOR XML RAW, ELEMENTS XSINIL);';
INSERT INTO @tmptbl EXEC(@cmd);
SELECT r.value('*[1]/text()[1]','nvarchar(max)') AS RowID
,c.value('local-name(.)','nvarchar(max)') AS ColumnKey
,c.value('text()[1]','nvarchar(max)') AS ColumnValue
FROM @tmptbl t
CROSS APPLY t.TheContent.nodes('/row') A(r)
CROSS APPLY A.r.nodes('*[position()>1]') B(c)
END;
GO
EXEC Get_EAV_FROM_SELECT @SELECT='SELECT TOP 10 o.object_id,o.* FROM sys.objects o';
GO
--Clean-Up for test purpose
DROP PROCEDURE Get_EAV_FROM_SELECT;
简言之,这个想法
- select作为字符串传递到过程中。使用SP,我们动态创建一条语句并从中创建XML李>
- 第一列被认为是行的ID,如果不是(如在
中),我们可以编写SELECT并以这种方式强制它sys.objects
- 内部
将读取每一行并返回一个经典的EAV列表SELECT
CustomerID
、key(Attribute)
和value
。我正在编写一个存储过程,该过程将表名和客户Id列名作为参数,并将它们写入键/值表。您使用的是哪种数据库?@Grimm Microsoft SQL Server 2017I对于如何在关系数据库(如SQL Server 2017)上创建没有特定结构的表有些恼火。。。你能告诉我们更多的背景吗?@Grimm我们的分析师将他们的分析报告保存在数据库的表格中。但外部系统接受键/值格式的数据。分析员完成的每个表都应该包含一列CustomerID,但所有其他列都应该转换为键/值行,以便在目标表中,每行都有CustomerID
、key(Attribute)
和value
。我正在编写一个存储过程,它将表名和客户Id列名作为参数,并将它们写入键/值表中。如果您能看一看,我将不胜感激。否则,我同意你的回答。我试图用另一个问题中的样本数据来解释这种情况。如果您能看一看,我将不胜感激。我同意你的回答,否则。有趣的方法。虽然我不是提问者,但我学到了一些新东西。非常感谢(我投了赞成票)。很有趣的方法。虽然我不是提问者,但我学到了一些新东西。非常感谢(我投了赞成票)。