简体   繁体   English

无法解决SELECT语句中第4列的排序规则冲突

[英]Cannot resolve collation conflict for column 4 in SELECT statement

I am trying to get some SQL to execute but am getting the following error 我试图让一些SQL执行,但我得到以下错误

    Msg 451, Level 16, State 1, Line 1
Cannot resolve collation conflict for column 4 in SELECT statement.

But cannot seem to figure out where the problem is??? 但似乎无法弄清楚问题出在哪里??? Any help would be very much appreciated. 任何帮助将非常感谢。

SELECT     MEMBTYPEID.text AS MemberType, MEMBLST.nodeId, MEMBTYPES.Name AS MemberField, 
                      ISNULL(CASE WHEN MEMBTYPES.datatypeID IN
                          (SELECT     NodeId
                            FROM          DBO.CMSDATATYPE
                            WHERE      DBTYPE = 'Nvarchar') THEN MEMBDATA.[dataNvarchar] WHEN MEMBTYPES.datatypeID IN
                          (SELECT     NodeId
                            FROM          DBO.CMSDATATYPE
                            WHERE      DBTYPE = 'Ntext') THEN MEMBDATA.[dataNtext] WHEN MEMBTYPES.datatypeID IN
                          (SELECT     NodeId
                            FROM          DBO.CMSDATATYPE
                            WHERE      DBTYPE = 'Date') THEN CONVERT(NVARCHAR, MEMBDATA.[dataDate]) WHEN MEMBTYPES.datatypeID IN
                          (SELECT     NodeId
                            FROM          DBO.CMSDATATYPE
                            WHERE      DBTYPE = 'Integer') THEN CASE WHEN
                          (SELECT     value
                            FROM          [dbo].[cmsDataTypePreValues]
                            WHERE      datatypenodeid = MEMBTYPES.[dataTypeId] AND id = CONVERT(INT, MEMBDATA.[dataInt])) IS NOT NULL THEN
                          (SELECT     value
                            FROM          [dbo].[cmsDataTypePreValues]
                            WHERE      datatypenodeid = MEMBTYPES.[dataTypeId] AND id = CONVERT(INT, MEMBDATA.[dataInt])) ELSE CONVERT(NVARCHAR, 
                      MEMBDATA.[dataInt]) END ELSE NULL END, '') AS MemberData
FROM         (SELECT     id, text
                       FROM          dbo.umbracoNode
                       WHERE      (nodeObjectType = '9b5416fb-e72f-45a9-a07b-5a9a2709ce43')) AS MEMBTYPEID LEFT OUTER JOIN
                          (SELECT     nodeId, contentType
                            FROM          dbo.cmsContent) AS MEMBLST ON MEMBLST.contentType = MEMBTYPEID.id LEFT OUTER JOIN
                      dbo.cmsPropertyType AS MEMBTYPES ON MEMBTYPES.contentTypeId = MEMBLST.contentType LEFT OUTER JOIN
                      dbo.cmsPropertyData AS MEMBDATA ON MEMBDATA.contentNodeId = MEMBLST.nodeId AND 
                      MEMBDATA.propertytypeid = MEMBTYPES.id LEFT OUTER JOIN
                      dbo.cmsMember AS MEMB ON MEMB.nodeId = MEMBLST.nodeId
WHERE     (MEMBLST.nodeId IS NOT NULL)

My SQL skills are fairly basic, so hope someone can help 我的SQL技能非常基础,所以希望有人可以提供帮助

~~~~~~~~~~~~ WORKING CODE ~~~~~~~~~~~~~ ~~~~~~~~~~~~工作代码~~~~~~~~~~~~~

Managed to get it working and here is the code 管理让它工作,这是代码

SELECT MEMBTYPEID.text AS MemberType, MEMBLST.nodeId, MEMBTYPES.Name AS MemberField, MEMBTYPES.Alias AS MemberFieldAlias, MEMB.LoginName,
ISNULL(CASE 
WHEN MEMBTYPES.datatypeID IN (SELECT NodeId FROM DBO.CMSDATATYPE WHERE DBTYPE = 'Nvarchar') THEN MEMBDATA.[dataNvarchar] 
WHEN MEMBTYPES.datatypeID IN (SELECT NodeId FROM DBO.CMSDATATYPE WHERE DBTYPE = 'Ntext') THEN MEMBDATA.[dataNtext] 
WHEN MEMBTYPES.datatypeID IN (SELECT NodeId FROM DBO.CMSDATATYPE WHERE DBTYPE = 'Date') THEN CONVERT(NVARCHAR, MEMBDATA.[dataDate]) 
WHEN MEMBTYPES.datatypeID IN (SELECT NodeId FROM DBO.CMSDATATYPE WHERE DBTYPE = 'Integer') THEN  CONVERT(NVARCHAR, MEMBDATA.[dataInt])
ELSE NULL END, NULL) 
AS MemberData 
FROM 
(SELECT id, text FROM dbo.umbracoNode WHERE (nodeObjectType = '9b5416fb-e72f-45a9-a07b-5a9a2709ce43')) AS MEMBTYPEID 
LEFT OUTER JOIN (SELECT nodeId, contentType FROM dbo.cmsContent) AS MEMBLST ON MEMBLST.contentType = MEMBTYPEID.id 
LEFT OUTER JOIN dbo.cmsPropertyType AS MEMBTYPES ON MEMBTYPES.contentTypeId = MEMBLST.contentType 
LEFT OUTER JOIN dbo.cmsPropertyData AS MEMBDATA ON MEMBDATA.contentNodeId = MEMBLST.nodeId AND MEMBDATA.propertytypeid = MEMBTYPES.id 
LEFT OUTER JOIN dbo.cmsMember AS MEMB ON MEMB.nodeId = MEMBLST.nodeId
WHERE (MEMBLST.nodeId IS NOT NULL)

A collation is basically a codepage that tells sql how to interpret/compare/sort strings . 排序规则基本上是一个代码页,告诉sql如何解释/比较/排序字符串。 It can be for example be case (in)sensitive or (not) ignore accents (like ^ in French). 它可以是例如case(in)敏感或(不)忽略重音(如法语中的^)。 Fore more info, see here . 更多信息, 请看这里

In sql server, you set the collation on the server/database/column level where each lower level can override the default of the higher level. 在sql server中,您可以在服务器/数据库/列级别设置排序规则,其中每个较低级别可以覆盖较高级别的默认值。 That makes it possible that you will compare strings from two different collations. 这使您可以比较两种不同排序规则的字符串。 And that's where the catch. 这就是捕获的地方。 Sometimes it's impossible to compare 2 different collations. 有时候不可能比较两种不同的排序规则。 For example, if column 1 has a case insensitive collation and column 2 a case sensitive and you compare 'AAA' from column 1 with 'aaa' from column 2, are they equal or not ? 例如,如果第1列具有不区分大小写的排序规则而第2列具有区分大小写,并且您将第1列的“AAA”与第2列的“aaa”进行比较,它们是否相等? In such a case, sql throws a collation error. 在这种情况下,sql会抛出排序规则错误。

column 4 refers to your MemberData column ie the giant ISNULL(Case ... statement. Sql collation conflicts typically happen with compares between strings so that means one of your IN or = operators is the culprit. To debug, I would gradually remove parts of that statement until the error doesn't happen anymore. Then check the collation of the columns in the part you just removed. If they are different, it's very likely that's your problem. column 4引用你的MemberData列,即巨大的ISNULL(Case ...语句.Sql排序规则冲突通常发生在字符串之间的比较,这意味着你的IN或=运算符之一是罪魁祸首。要调试,我会逐渐删除部分那句话直到错误不再发生。然后检查你刚删除的部分中列的整理。如果它们不同,很可能是你的问题。

You then could use COLLATE to force the string of one of those columns to cast to the collation of the other column. 然后,您可以使用COLLATE强制将其中一列的字符串强制转换为另一列的排序规则。 Be warned however that depending on your collation you can get weird compare results ie 'Â' can be equal to 'a' or not. 但请注意,根据您的校对,您可以获得奇怪的比较结果,即“”可以等于“a”。 I would try to pin down which strings in your columns are giving the collation error so that you can see what would be the effect from using COLLATE. 我会尝试确定列中的哪些字符串给出排序错误,以便您可以看到使用COLLATE会产生什么影响。

As a general rule, I would recommend to never override the default collation of your database just to prevent this sort of headaches. 作为一般规则,我建议永远不要覆盖数据库的默认排序规则,以防止这种令人头疼的问题。

For the fourth column, I suspect that something either side of the '=' is a different collation. 对于第四列,我怀疑'='的任何一侧是不同的排序规则。 You could try putting 'collate database_default' either side of the '='. 您可以尝试在'='的任一侧放置'collat​​e database_default'。 If you try 'SP_HELP' on each of the table names used by the fourth column, this will help you to see if there are any differences in the collation at the column level. 如果在第四列使用的每个表名上尝试“SP_HELP”,这将帮助您查看列级别的排序规则是否存在任何差异。 It's not the type of data that's the issue, it's the type of collation of the column. 这不是问题的数据类型,而是列的整理类型。 As SemVanmeenen has said above, for the query affecting the 4th column, try to remove some of the parts of the statement and try to run it, and then put them in again. 正如SemVanmeenen上面所说,对于影响第4列的查询,尝试删除语句的某些部分并尝试运行它,然后再将它们放入。 That might help you to identify the offending line of code. 这可能有助于您识别有问题的代码行。 Good luck! 祝好运! Please let us know how you get on. 请告诉我们您的情况。 Regards, Jen Stirrup www.jenstirrup.com 此致,Jen Stirrup www.jenstirrup.com

Do you have "collate" columns in your tables ? 你的表中有“整理”列吗?

If true you should add "collate" after their names. 如果为true,则应在其名称后添加“collat​​e”。 As an exemple if cmsPropertyType.contentTypeId is a collate column. 作为示例,如果cmsPropertyType.contentTypeId是整理列。 Instead of : ON MEMBTYPES.contentTypeId = MEMBLST.contentType 而不是:ON MEMBTYPES.contentTypeId = MEMBLST.contentType

You should write : ON MEMBTYPES.contentTypeId collate 'contentTypeIdCollateAlias' = MEMBLST.contentType 您应该写:ON MEMBTYPES.contentTypeId整理'contentTypeIdCollat​​eAlias'= MEMBLST.contentType

Check out documentation : Doc on MSDN 查看文档: MSDN上的Doc

And read the SemVanmeen's post for a better understanding of your probleme 阅读SemVanmeen的帖子,以便更好地了解您的问题

Two suspects. 两名嫌犯。

First one is this: 首先是:

SELECT     value
FROM          [dbo].[cmsDataTypePreValues]
WHERE      datatypenodeid = MEMBTYPES.[dataTypeId] AND id = CONVERT(INT, MEMBDATA.[dataInt])

What type is value ? 什么类型的value It should probably be nvarchar , otherwise you should convert it accordingly. 它可能应该是nvarchar ,否则你应该相应地转换它。

Second one is the default '' in the ISNULL . 第二个是ISNULL的默认值'' Maybe you should define it as N'' ? 也许你应该把它定义为N''

Also, regarding the subselect, why does it have to be repeated twice, in WHEN , and afterwards in THEN ? 此外,关于子选择,它为什么要重复两次, WHEN ,事后在THEN You could replace that sub- CASE completely with COALESCE((SELECT value...), CONVERT(NVARCHAR, MEMBDATA.[dataInt])) . 您可以使用COALESCE((SELECT value...), CONVERT(NVARCHAR, MEMBDATA.[dataInt]))完全替换该子CASE

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM