我需要从数据库中的一个表中查询某些内容,但是某些列的排序规则与我需要的排序规则不同。
我发现了如何动态更改一列的排序规则:
SELECT
u.name COLLATE Latin1_General_CI_AS AS 'User'(...)
但是问题是有超过150列需要即时更改COLLATION(不要问我为什么,因为即使我认为这是最好的选择,我们也不能更改整个表的排序规则)。
所以主要问题是:
Is there a way to set the COLLATION to all columns of my query?
答案 0 :(得分:1)
我不确定是否可以通过这种方式对输出的所有列强制使用默认排序规则。
但是,如果您的服务器允许您使用动态SQL,则可以构建动态查询并执行它以获取所需的结果。
此工作的示例如下所示。请将YOUR_TABLE_NAME
更改为您的实际表名,以使其起作用:
DECLARE @col VARCHAR(200)
DECLARE @sql VARCHAR(MAX)
DECLARE @table VARCHAR(200)
SET @table = 'YOUR_TABLE_NAME';
-- Use a cursor to read all varchar columns from table
DECLARE curColumns CURSOR FORWARD_ONLY STATIC READ_ONLY
FOR
SELECT c.name
FROM sys.columns c
INNER JOIN sys.types t ON c.user_type_id = t.user_type_id
WHERE c.object_id = OBJECT_ID(@table) AND
t.name = 'varchar'
SET @sql = 'SELECT'
-- Go through column cursor
OPEN curColumns
FETCH NEXT FROM curColumns INTO @col
WHILE (@@FETCH_STATUS = 0)
BEGIN
-- Add column to SQL with collation
SET @sql = @sql + ' ' + @col + ' COLLATE Latin1_General_CI_AS,'
FETCH NEXT FROM curColumns INTO @col
END
CLOSE curColumns
DEALLOCATE curColumns
-- Add the from clause
SET @sql = SUBSTRING(@sql, 0, LEN(@sql) - 1) + ' FROM ' + @table
-- Uncomment this line to see the generated SQL
--PRINT @sql
EXEC (@sql)
请注意,上面的示例有几个限制:
VARCHAR
列(您可以通过更改光标查询以包括更多类型来更改此列)。答案 1 :(得分:1)
无法即时更改所有文本列的排序规则-但是可以通过操纵查询来获得相同的结果。 Martin's answer显示了一种方法,这是使用查询元数据的另一种方法。好处是,它没有游标,并且如果排序规则已经是我们想要的,它就避免了不必要地引入“新”列。它要求至少SQL Server 2012具有sys.dm_exec_describe_first_result_set
,SQL Server 2017具有STRING_AGG
(在以前的版本中,可以使用经典的字符串串联技巧,例如FOR XML PATH
技巧)
DECLARE @query NVARCHAR(MAX) = N'SELECT * FROM MyTable';
DECLARE @tweakedQuery NVARCHAR(MAX);
DECLARE @tweakedCollation SYSNAME = N'Latin1_General_CI_AS';
SELECT @tweakedQuery = CONCAT(
'SELECT ',
STRING_AGG(
CONCAT(
CONVERT(NVARCHAR(MAX), QUOTENAME([name])),
CASE
WHEN collation_name IS NOT NULL AND collation_name <> @tweakedCollation
THEN ' COLLATE ' + @tweakedCollation + ' AS ' + QUOTENAME([name])
END
),
', ' + CHAR(13) + CHAR(10)
),
' FROM (' + CHAR(13) + CHAR(10),
@query,
CHAR(13) + CHAR(10) + ') _'
)
FROM sys.dm_exec_describe_first_result_set(@query, NULL, NULL);
PRINT @tweakedQuery;
如果自定义别名是系统生成的(基于表名或列名),则合并起来很简单。否则,您将不得不手动修补问题。
对于一次性查询(不一定需要即时执行),使自己熟悉自己喜欢的编辑器中的正则表达式仍然是一个更好的主意。如果您最喜欢的编辑器没有正则表达式,请获取一个。