【问题标题】:Update table variable更新表变量
【发布时间】:2016-07-15 18:32:34
【问题描述】:

我有一个表变量@searchResult

DECLARE @searchResult TABLE (
    [name_template] NVARCHAR(50),
    [record_id] INT,
    [record_name] NVARCHAR(50)
);

还有表[records]

CREATE TABLE [records] (
    [record_id] INT IDENTITY(1, 1) PRIMARY KEY,
    [record_name] NVARCHAR(50)
)

@searchResult 包含仅填充了[name_template] 的记录。我想用匹配[name_template][records] 表中的最新[record_id][record_name] 更新它。

我尝试了以下 SQL 查询但没有成功:

UPDATE @searchResult
SET [record_id] = r.[record_id], [record_name] = r.[record_name]
FROM (
    SELECT TOP 1
          r.[record_id]
        , r.[record_name]
    FROM [records] AS r
    WHERE r.[record_name] LIKE [name_template]
    ORDER BY r.[record_id] DESC
) AS r;

错误信息:

列名“name_template”无效。

用所需值更新@searchResult 的正确语法是什么?

【问题讨论】:

  • 查看正在用于更新的查询。我假设表记录没有名为 name_template 的列?它是您的表变量。请记住,您的查询必须自行执行。这意味着在这种情况下,您必须在查询中加入表变量。
  • 引号丢失 ..like 'name_template' 或 like '%name_template%'

标签: sql sql-server sql-server-2008


【解决方案1】:

你需要在桌子上做一个CROSS APPLY

UPDATE @searchResult
SET [record_id] = r.[record_id], 
    [record_name] = r.[record_name]
FROM @searchResult SR
CROSS APPLY (
    SELECT TOP 1 *
    FROM [records]
    WHERE [record_name] LIKE [name_template]   -- Your wish, but do you really need LIKE matching??
    ORDER BY [record_id] DESC
) AS r;

【讨论】:

  • 这个查询成功了! PS 我真的很想使用 LIKE 因为 [name_template] 包含特殊字符 %_ 用于通配符搜索
【解决方案2】:

试试这个:

UPDATE t
SET [record_id] = r.[record_id], 
    [record_name] = r.[record_name]
FROM @searchResult t
INNER JOIN 
(
    SELECT MAX([record_id]) As [record_id]
            ,[record_name]
    FROM [records]
    GROUP BY [record_name] 
) r
ON r.[record_name] LIKE t.[name_template];

更新:
根据我的测试,似乎工作正常:

创建表和表变量:

CREATE TABLE [records] (
    [record_id] INT IDENTITY(1, 1) PRIMARY KEY,
    [record_name] NVARCHAR(50)
)

DECLARE @searchResult TABLE (
    [name_template] NVARCHAR(50),
    [record_id] INT,
    [record_name] NVARCHAR(50)
);

填充样本数据:

INSERT INTO [records] ([record_name]) VALUES('a'), ('a'), ('a'), ('b'), ('b')

INSERT INTO @searchResult ([name_template]) VALUES ('a'), ('b')

更新表变量:

UPDATE t
SET [record_id] = r.[record_id], 
    [record_name] = r.[record_name]
FROM @searchResult t
INNER JOIN 
(
    SELECT MAX([record_id]) As [record_id]
            ,[record_name]
    FROM [records]
    GROUP BY [record_name] 
) r
ON r.[record_name] LIKE t.[name_template];

检查结果:

SELECT *
FROM records

SELECT *
FROM @searchResult

DROP TABLE records 

结果:

records
record_id   record_name
----------- -----------
1           a
2           a
3           a
4           b
5           b

@searchResult
name_template   record_id   record_name
-------------   ---------   -----------
a               3           a
b               5           b

【讨论】:

  • 此查询有效,但它不会使用最新数据更新 [record_id] 和 [record_name]。
  • 感谢您的努力。这是无法使用最新数据更新时的示例(保留您的测试数据并添加此数据):INSERT INTO [records] ([record_name]) VALUES('ab'); INSERT INTO @searchResult ([name_template]) VALUES ('a%') 我希望 @searchResult for [name_template] 'a%' 在更新语句后包含 [record_id] of 'ab'
  • 为此,您需要一个动态 sql 解决方案。 Sql server 不会将表变量中的% 视为通配符,而是将其视为字符串的一部分。但是,如果您可以更改表变量,则有一些方法可以解决。
  • 我不确定是否有特殊设置对此负责,但在我的情况下,表变量中的 % 被视为我期望的那样(匹配任意数量的字符)
  • 好吧,看来这是我的错误。至少你得到了你问题的答案,以及样本数据重要性的教训......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多