我正在从SQL SERVER 2008 R2到WINDOWS AZURE创建这个SQL函数,但我不知道如何解决这个问题。
消息468,等级16,状态9,程序GetObjectivesByTest,第69行 无法解决之间的整理冲突 “SQL_Latin1_General_CP1_CI_AS”和“Modern_Spanish_CI_AS”在平等 操作。
CREATE FUNCTION [dbo].[GetObjectivesByTest](@testId smallint)
RETURNS
@res TABLE
(
-- Add the column definitions for the TABLE variable here
ObjectiveId smallint NOT NULL,
Name nvarchar(50) NOT NULL,
Expectations nvarchar(400) NULL,
[Level] nvarchar(5) NOT NULL,
ParentId smallint NULL,
LearningSystem nvarchar(30) NULL,
[Rank] tinyint NULL
)
AS
BEGIN
DECLARE @string VARCHAR(MAX)
SELECT @string = OBJECTIVES FROM TESTS WHERE TestId = @testId
DECLARE @temp TABLE
(
ColumnA NVARCHAR(50),
ColumnB NVARCHAR(500),
ID INT IDENTITY(1,1)
)
INSERT INTO @temp (ColumnA, ColumnB) VALUES ('', @string)
DECLARE @idx INT, @cnt INT
SET @idx = 1
SELECT @cnt = COUNT(*) FROM @temp
DECLARE @SplitStr nvarchar(1000),
@SplitChar nvarchar(5),
@Columns VARCHAR(50)
SET @SplitChar = ','
WHILE @idx <= @cnt BEGIN
SELECT @SplitStr = ColumnB
FROM @temp
WHERE id = @idx
DECLARE @RtnValue table
(
ColumnName VARCHAR(50),
Data VARCHAR(50)
)
Declare @Count int
Set @Count = 1
While (Charindex(@SplitChar,@SplitStr)>0) Begin
Insert Into @RtnValue (ColumnName,Data)
Select @Columns, Data = ltrim(rtrim(Substring(@SplitStr,1,Charindex(@SplitChar,@SplitStr)-1)))
Set @SplitStr = Substring(@SplitStr,Charindex(@SplitChar,@SplitStr)+1,len(@SplitStr))
Set @Count = @Count + 1
End
Insert Into @RtnValue (ColumnName,Data)
Select @Columns,Data = ltrim(rtrim(@SplitStr))
SET @idx = @idx + 1
END
INSERT @RES // here is appointing the error
SELECT C.*
FROM Objectives AS C
INNER JOIN OBJECTIVES AS B ON (C.ParentId = B.ObjectiveId)
INNER JOIN OBJECTIVES AS A ON (B.ParentId = A.ObjectiveId)
where C.Rank = 3 AND B.Rank = 2 AND A.Rank = 1 AND
A.LearningSystem + ' ' + A.Level + '.' + C.Level IN (SELECT Data FROM @RtnValue)
RETURN
END
我对这个问题一无所知,如何解决这种不兼容问题。 提前谢谢。
答案 0 :(得分:7)
数据库排序规则(@ RtnValue.Data)与Objectives.LearningSysten中使用的排序规则之间存在排序规则不匹配。
最快的解决方案可能是在@RtnValue中明确声明排序规则:
DECLARE @RtnValue table
(
ColumnName VARCHAR(50),
Data VARCHAR(50) COLLATE [insert required collation name]
)
这是一个快速修复,但是,您应该检查数据库和表列级别上的排序规则的正确使用。
答案 1 :(得分:2)
Collation定义SQL Server如何比较字符串值,并在SQL Server中的各个级别指定:
你应该记住一些事情:
您无法隐式地将字符串值与不同的排序规则进行比较。虽然正确的做法是使用正确的整理,但有一些简单的解决方法。以下是您的选择,按复杂程度递增:
如果这是一个孤立的查询,其中临时表字符串列与数据库中的相应值进行比较,或者您赶时间并且只是想让它工作,您可以指定排序规则在WHERE
子句中。只要将数据库中的字符串值与T-SQL查询中的局部变量进行比较,就需要执行此操作:
WHERE C.Rank = 3 AND B.Rank = 2 AND A.Rank = 1
AND A.LearningSystem + ' ' + A.Level + '.' + C.Level COLLATE SQL_Latin1_General_CP1_CI_AS IN (SELECT Data COLLATE SQL_Latin1_General_CP1_CI_AS FROM @RtnValue)
您的下一个选项,也许是最佳解决方案,是匹配数据库默认排序规则和数据库中所有字符串列中使用的排序规则。更改数据库排序规则就像调用ALTER DATABASE MyDB COLLATE SQL_Latin1_General_CP1_CI_AS
一样简单,如MSDN Technet文章Set or Change the Database Collation中所述。但是,它不会为您更改数据库中列的排序规则。但是,您可以使用系统表生成一个脚本来执行此操作。我的机器上没有SQL Server,所以我无法对此进行测试,但这会给你一般的想法。运行脚本,将结果复制到SQL窗格中,然后运行它。
WITH cte AS (SELECT o.name AS TableName, c.name AS ColumnName, t.name AS TypeName, c.max_length AS MaxLen
FROM sys.objects o INNER JOIN sys.columns c ON o.object_id = c.object_id
INNER JOIN sys.types t ON t.system_type_id = c.system_type_id
WHERE o.type = 'U'
AND t.name IN ('char', 'nchar', 'varchar', 'nvarchar'))
SELECT 'ALTER TABLE ' + TableName + ' ALTER COLUMN ' + ColumnName + ' ' + TypeName + '('
+ CAST(CASE WHEN SUBSTRING(TypeName, 1, 1) = 'n' THEN MaxLen/2 ELSE MaxLen END AS VARCHAR) + ') COLLATE SQL_Latin1_General_CP1_CI_AS'
FROM cte
请注意,使用此解决方案,您仍需要为临时表中使用的任何列指定排序规则,无论这些列是在存储过程还是原始T-SQL命令的上下文中。但是,这是一种很好的做法,因为如果将此数据库部署到已拥有自己的数据库服务器且希望使用同一服务器的客户,则不能指望他们必须更改其服务器的默认排序规则。
答案 2 :(得分:0)
这些很难看。我知道有两种方法可以解决这个问题,而且都不是那么优雅:
更改其中一个数据库的排序规则以匹配另一个:http://msdn.microsoft.com/en-us/library/ms175835(v=sql.105).aspx
或者更改查询/表中每列的排序规则以匹配目标数据库:http://msdn.microsoft.com/en-us/library/ms190920(v=sql.105).aspx