使用来自其他列的值查找和替换花括号中的值
Find and Replace values in curly braces with values coming from other column
我在编写 SQL 查询时遇到问题。
我有一个数据 table 包含以下几列。
数据表 1
id notes
----------------------------------------------------------------
1 The Organization
1 develop document disseminate to {{param = "ac-1_prm_1"}}
2 develop document to {{param = "ac-1_prm_2"}}
2 Test
数据table参数
parameterid value. Id
-------------------------------—————----------------
ac-1_prm_1 apple doc. 1
ac-1_prm_2 google doc. 1
ac-1_prm_3 facebook doc. 2
我需要创建一个 final_notes
列:
id notes final_notes
---------------------------------------------------------------------------------------------
1 The Organization The Organization
1 develop document disseminate develop document disseminate to apple
to{<!-- -->{param = "ac-1_prm_1"}} doc and google doc
and {<!-- -->{param = "ac-1_prm_2"}}
2 develop document develop document facebook doc
to {<!-- -->{param = "ac-1_prm_3"}}
2 Test Test
Sql 代码无效。
在我的代码中,我必须硬编码我不想要的值。
DECLARE @DataTable TABLE (
id int,
notes varchar(1000)
);
INSERT INTO @DataTable VALUES
(1, 'Organization'),
(1, 'develop document disseminate to {{param = "ac-1_prm_1"}} and
{{param = "ac-1_prm_2"}} '),
(2, 'develop document to {{param = "ac-1_prm_3"}}'),
(2, 'test');
DECLARE @DataTableParameter TABLE (
parameterid varchar(100),
[value] varchar(100),
id int
);
INSERT INTO @DataTableParameter VALUES
('ac-1_prm_1', 'apple doc.', 1),
('ac-1_prm_2', 'google doc.', 1),
('ac-1_prm_3', 'facebook doc.', 2)
;WITH CTE AS (
SELECT t1.id, t1.notes, t2.parameterid, t2.value
FROM @DataTable AS t1
INNER JOIN @DataTableParameter AS t2 ON t1.id = t2.id
)
SELECT
t.id,
REPLACE('develop document disseminate to {' + STUFF(
(
SELECT ', {' + parameterid + '}'
FROM CTE
WHERE id = t.id
ORDER BY parameterid
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),
1,
1,
''
) + '}', ',', ' and ') AS notes,
REPLACE(REPLACE('develop document disseminate to ' + STUFF(
(
SELECT ', ' + value
FROM CTE
WHERE id = t.id
ORDER BY value
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),
1,
1,
''
), '.', ''), ',', ' and ') AS final_notes
FROM CTE AS t
GROUP BY t.id;
请尝试以下解决方案。
SQL
-- DDL and sample data population, start
DECLARE @DataTable TABLE (id int, notes varchar(1000));
INSERT INTO @DataTable VALUES
(1, 'Organization'),
(1, 'develop document disseminate to {{param = "ac-1_prm_1"}} and
{{param = "ac-1_prm_2"}} '),
(2, 'develop document to {{param = "ac-1_prm_3"}}'),
(2, 'test');
DECLARE @DataTableParameter TABLE (parameterid varchar(100), [value] varchar(100), id int);
INSERT INTO @DataTableParameter VALUES
('ac-1_prm_1', 'apple doc.', 1),
('ac-1_prm_2', 'google doc.', 1),
('ac-1_prm_3', 'facebook doc.', 2);
-- DDL and sample data population, end
DECLARE @parameterid varchar(100), @value VARCHAR(100);
DECLARE @RowCount INT = (SELECT COUNT(*) FROM @DataTableParameter);
WHILE @RowCount > 0 BEGIN
SELECT @parameterid = parameterid, @value = value
FROM @DataTableParameter
ORDER BY ID DESC OFFSET @RowCount - 1 ROWS FETCH NEXT 1 ROWS ONLY;
-- do whatever needed, apply any logic, call stored procedures, etc.
UPDATE @DataTable
SET notes = REPLACE(notes, CONCAT('{{param = "', @parameterid, '"}}'), @value);
SET @RowCount -= 1;
END;
-- test
SELECT * FROM @DataTable;
输出
+----+--------------------------------------------------------------+
| id | notes |
+----+--------------------------------------------------------------+
| 1 | Organization |
| 1 | develop document disseminate to apple doc. and google doc. |
| 2 | develop document to facebook doc. |
| 2 | test |
+----+--------------------------------------------------------------+
递归 CTE 在这里可能会相当笨拙,因为您不能使用 TOP
并且您还必须仅过滤最终结果。
而是使用 table 变量或临时变量 table,并循环更新它。
DECLARE @results TABLE (id int, notes varchar(1000));
INSERT @results (id, notes)
SELECT id, notes
FROM @DataTable dt;
DECLARE @dtp varchar(100), @dtv varchar(100);
WHILE 1=1
BEGIN
SELECT TOP (1)
@dtp = dtp.parameterid,
@dtv = dtp.value
FROM @DataTableParameter dtp
WHERE parameterid > @dtp OR @dtp IS NULL
ORDER BY parameterid;
IF @@ROWCOUNT = 0
BREAK;
UPDATE @results
SET
notes = REPLACE(notes, '{{param = "' + @dtp + '"}}', @dtv)
FROM @results r
WHERE notes LIKE '%' + @dtp + '%';
END;
SELECT *
FROM @results;
这可能是 古怪更新的情况:
CREATE DATABASE testDb_Shnugo;
GO
USE testDb_Shnugo;
GO
--用你的测试数据创建tables
CREATE TABLE dbo.DataTable (id INT, notes VARCHAR(1000));
INSERT INTO dbo.DataTable VALUES
(1, 'The Organization'),
(1, 'develop document disseminate to {{param = "ac-1_prm_1"}} and {{param = "ac-1_prm_2"}} '),
(2, 'develop document to {{param = "ac-1_prm_3"}}'),
(2, 'test');
GO
CREATE TABLE DataTableParameter (parameterid VARCHAR(100), [value] VARCHAR(100), id INT);
INSERT INTO DataTableParameter VALUES
('ac-1_prm_1', 'apple doc.', 1),
('ac-1_prm_2', 'google doc.', 1),
('ac-1_prm_3', 'facebook doc.', 2);
GO
--魔法来了:古怪的更新
CREATE FUNCTION dbo.MultiReplaceDataTableParameters(@inp VARCHAR(1000), @id INT)
RETURNS VARCHAR(1000)
AS
BEGIN
DECLARE @result VARCHAR(1000)=@inp;
SELECT @result = REPLACE(@result,CONCAT('{{param = "',dtp.parameterid,'"}}'),dtp.[value])
FROM dbo.DataTableParameter dtp
WHERE dtp.id=@id;
RETURN @result;
END
GO
--试试看
SELECT *
,dbo.MultiReplaceDataTableParameters(dt.notes,dt.id) AS ReplacedText
FROM dbo.DataTable dt
ORDER BY dt.id;
GO
--清理(注意真实数据!)
USE master;
GO
DROP DATABASE testDb_Shnugo;
简而言之:
古怪更新 遍历 table 的结果并使用声明的参数作为输入 和 分配。因此,该值将随着访问的任何行而变化。
这允许一次执行多项操作。
有充分的理由避免这种技术,但在这种情况下它可能会有所帮助。
1 The Organization
1 develop document disseminate to apple doc. and google doc.
2 develop document to facebook doc.
2 test
我在编写 SQL 查询时遇到问题。
我有一个数据 table 包含以下几列。
数据表 1
id notes
----------------------------------------------------------------
1 The Organization
1 develop document disseminate to {{param = "ac-1_prm_1"}}
2 develop document to {{param = "ac-1_prm_2"}}
2 Test
数据table参数
parameterid value. Id
-------------------------------—————----------------
ac-1_prm_1 apple doc. 1
ac-1_prm_2 google doc. 1
ac-1_prm_3 facebook doc. 2
我需要创建一个 final_notes
列:
id notes final_notes
---------------------------------------------------------------------------------------------
1 The Organization The Organization
1 develop document disseminate develop document disseminate to apple
to{<!-- -->{param = "ac-1_prm_1"}} doc and google doc
and {<!-- -->{param = "ac-1_prm_2"}}
2 develop document develop document facebook doc
to {<!-- -->{param = "ac-1_prm_3"}}
2 Test Test
Sql 代码无效。
在我的代码中,我必须硬编码我不想要的值。
DECLARE @DataTable TABLE (
id int,
notes varchar(1000)
);
INSERT INTO @DataTable VALUES
(1, 'Organization'),
(1, 'develop document disseminate to {{param = "ac-1_prm_1"}} and
{{param = "ac-1_prm_2"}} '),
(2, 'develop document to {{param = "ac-1_prm_3"}}'),
(2, 'test');
DECLARE @DataTableParameter TABLE (
parameterid varchar(100),
[value] varchar(100),
id int
);
INSERT INTO @DataTableParameter VALUES
('ac-1_prm_1', 'apple doc.', 1),
('ac-1_prm_2', 'google doc.', 1),
('ac-1_prm_3', 'facebook doc.', 2)
;WITH CTE AS (
SELECT t1.id, t1.notes, t2.parameterid, t2.value
FROM @DataTable AS t1
INNER JOIN @DataTableParameter AS t2 ON t1.id = t2.id
)
SELECT
t.id,
REPLACE('develop document disseminate to {' + STUFF(
(
SELECT ', {' + parameterid + '}'
FROM CTE
WHERE id = t.id
ORDER BY parameterid
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),
1,
1,
''
) + '}', ',', ' and ') AS notes,
REPLACE(REPLACE('develop document disseminate to ' + STUFF(
(
SELECT ', ' + value
FROM CTE
WHERE id = t.id
ORDER BY value
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),
1,
1,
''
), '.', ''), ',', ' and ') AS final_notes
FROM CTE AS t
GROUP BY t.id;
请尝试以下解决方案。
SQL
-- DDL and sample data population, start
DECLARE @DataTable TABLE (id int, notes varchar(1000));
INSERT INTO @DataTable VALUES
(1, 'Organization'),
(1, 'develop document disseminate to {{param = "ac-1_prm_1"}} and
{{param = "ac-1_prm_2"}} '),
(2, 'develop document to {{param = "ac-1_prm_3"}}'),
(2, 'test');
DECLARE @DataTableParameter TABLE (parameterid varchar(100), [value] varchar(100), id int);
INSERT INTO @DataTableParameter VALUES
('ac-1_prm_1', 'apple doc.', 1),
('ac-1_prm_2', 'google doc.', 1),
('ac-1_prm_3', 'facebook doc.', 2);
-- DDL and sample data population, end
DECLARE @parameterid varchar(100), @value VARCHAR(100);
DECLARE @RowCount INT = (SELECT COUNT(*) FROM @DataTableParameter);
WHILE @RowCount > 0 BEGIN
SELECT @parameterid = parameterid, @value = value
FROM @DataTableParameter
ORDER BY ID DESC OFFSET @RowCount - 1 ROWS FETCH NEXT 1 ROWS ONLY;
-- do whatever needed, apply any logic, call stored procedures, etc.
UPDATE @DataTable
SET notes = REPLACE(notes, CONCAT('{{param = "', @parameterid, '"}}'), @value);
SET @RowCount -= 1;
END;
-- test
SELECT * FROM @DataTable;
输出
+----+--------------------------------------------------------------+
| id | notes |
+----+--------------------------------------------------------------+
| 1 | Organization |
| 1 | develop document disseminate to apple doc. and google doc. |
| 2 | develop document to facebook doc. |
| 2 | test |
+----+--------------------------------------------------------------+
递归 CTE 在这里可能会相当笨拙,因为您不能使用 TOP
并且您还必须仅过滤最终结果。
而是使用 table 变量或临时变量 table,并循环更新它。
DECLARE @results TABLE (id int, notes varchar(1000));
INSERT @results (id, notes)
SELECT id, notes
FROM @DataTable dt;
DECLARE @dtp varchar(100), @dtv varchar(100);
WHILE 1=1
BEGIN
SELECT TOP (1)
@dtp = dtp.parameterid,
@dtv = dtp.value
FROM @DataTableParameter dtp
WHERE parameterid > @dtp OR @dtp IS NULL
ORDER BY parameterid;
IF @@ROWCOUNT = 0
BREAK;
UPDATE @results
SET
notes = REPLACE(notes, '{{param = "' + @dtp + '"}}', @dtv)
FROM @results r
WHERE notes LIKE '%' + @dtp + '%';
END;
SELECT *
FROM @results;
这可能是 古怪更新的情况:
CREATE DATABASE testDb_Shnugo;
GO
USE testDb_Shnugo;
GO
--用你的测试数据创建tables
CREATE TABLE dbo.DataTable (id INT, notes VARCHAR(1000));
INSERT INTO dbo.DataTable VALUES
(1, 'The Organization'),
(1, 'develop document disseminate to {{param = "ac-1_prm_1"}} and {{param = "ac-1_prm_2"}} '),
(2, 'develop document to {{param = "ac-1_prm_3"}}'),
(2, 'test');
GO
CREATE TABLE DataTableParameter (parameterid VARCHAR(100), [value] VARCHAR(100), id INT);
INSERT INTO DataTableParameter VALUES
('ac-1_prm_1', 'apple doc.', 1),
('ac-1_prm_2', 'google doc.', 1),
('ac-1_prm_3', 'facebook doc.', 2);
GO
--魔法来了:古怪的更新
CREATE FUNCTION dbo.MultiReplaceDataTableParameters(@inp VARCHAR(1000), @id INT)
RETURNS VARCHAR(1000)
AS
BEGIN
DECLARE @result VARCHAR(1000)=@inp;
SELECT @result = REPLACE(@result,CONCAT('{{param = "',dtp.parameterid,'"}}'),dtp.[value])
FROM dbo.DataTableParameter dtp
WHERE dtp.id=@id;
RETURN @result;
END
GO
--试试看
SELECT *
,dbo.MultiReplaceDataTableParameters(dt.notes,dt.id) AS ReplacedText
FROM dbo.DataTable dt
ORDER BY dt.id;
GO
--清理(注意真实数据!)
USE master;
GO
DROP DATABASE testDb_Shnugo;
简而言之:
古怪更新 遍历 table 的结果并使用声明的参数作为输入 和 分配。因此,该值将随着访问的任何行而变化。
这允许一次执行多项操作。
有充分的理由避免这种技术,但在这种情况下它可能会有所帮助。
1 The Organization
1 develop document disseminate to apple doc. and google doc.
2 develop document to facebook doc.
2 test