排序规则冲突SQL Server varchar存储过程参数

时间:2017-07-09 13:57:37

标签: sql sql-server collation

我使用REXTESTER编写一段SQL Server代码。

它表示正在使用它的SQL Server 2014 Express Edition ......

这是导致消息的最小代码。

CREATE PROCEDURE #CONVERT_TIME_TO_24_HR
(
  @TIME_STRING varchar(4)
)
AS
BEGIN
  DECLARE @AMPM as varchar(2);
  SET @AMPM = RIGHT(@TIME_STRING,2);
  IF @AMPM = 'am'
    SELECT 2
END
GO

这是错误:

Error(s), warning(s):
Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_CI_AS" in the equal to operation.

如果刚刚声明@TIME_STRING而不是存储过程的参数,我就不会有问题。由于我无法控制SQL Server实例,我该如何解决这个问题?

如果forked version不是参数,那么这是here - 没有问题

DECLARE @TIME_STRING varchar(4);
DECLARE @AMPM as varchar(2);
SET @AMPM = RIGHT(@TIME_STRING,2);
  IF @AMPM = 'am'
    SELECT 2

2 个答案:

答案 0 :(得分:2)

这是因为服务器/数据库/列的排序规则具有不同的值(可能是服务器和数据库)。您可以通过显式添加排序规则来修复它:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p>div1</p>
<div class="trailerdiv">
<button class="playtrailer">Trailer 1 </button>
<button class="playtrailer">Trailer 2 </button>
<button class="playtrailer">Trailer HD </button>
<button class="playtrailer">Trailer 5 </button>
<button class="playtrailer">Trailer 8 </button>
<button class="playtrailer">Video 3 </button>
</div>

<p>div2</p>

<div class="trailerdiv">
<button class="playtrailer">Trailer 1 </button>
<button class="playtrailer">Trailer 2 </button>
<button class="playtrailer">Trailer HD </button>
<button class="playtrailer">Trailer 5 </button>
<button class="playtrailer">Trailer 8 </button>
<button class="playtrailer">Video 3 </button>
</div>

<p>div3</p>

<div class="trailerdiv">
<button class="playtrailer">Trailer 1 </button>
<button class="playtrailer">Trailer 2 </button>
<button class="playtrailer">Trailer HD </button>
<button class="playtrailer">Trailer 5 </button>
<button class="playtrailer">Trailer 8 </button>
<button class="playtrailer">Video 3 </button>
</div>

我承认这不是一个常见的专栏。在您自己的系统上,默认排序规则可能都匹配。我不知道为什么Rextester的设计师会有不同的默认排序规则。

答案 1 :(得分:1)

另一个解决方案(对于戈登的解决方案+1)将使用COLLATE DATABASE_DEFAULT,这意味着当前数据库的整理。以下示例基于以下排序规则:

  1. &#39; Latin1_General_CI_AS&#39;对于tempdb数据库
  2. &#39; Romanian_CI_AS&#39; for current - DbCollat​​eDiffThanTempDbCollat​​ - database。
  3. 由于CREATE PROCEDURE #...语句在DbCollateDiffThanTempDbCollat数据库的上下文中使用COLLATE DATABASE_DEFAULT选项执行,这意味着IF @AMPM = 'am' COLLATE DATABASE_DEFAULTIF @AMPM = 'am' COLLATE Romanian_CI_AS等效(在此上下文中)。

    SELECT DATABASEPROPERTYEX('tempdb', 'Collation')
    /*
    
    ---------------------
    Latin1_General_CI_AS
    */
    GO
    
    CREATE DATABASE DbCollateDiffThanTempDbCollat
    COLLATE Romanian_CI_AS
    GO
    USE DbCollateDiffThanTempDbCollat
    GO
    SELECT DATABASEPROPERTYEX('DbCollateDiffThanTempDbCollat', 'Collation')
    GO
    /*
    
    --------------
    Romanian_CI_AS
    */
    
    USE DbCollateDiffThanTempDbCollat -- Current database for COLLATE DEFAULT_DATABASE is DbCollateDiffThanTempDbCollat -> COLLATE Romanian_CI_AS
    GO
    CREATE PROCEDURE #CONVERT_TIME_TO_24_HR
    (
      @TIME_STRING varchar(4)
    )
    AS
    BEGIN
      DECLARE @AMPM as varchar(2);
      SET @AMPM = RIGHT(@TIME_STRING,2);
      IF @AMPM = 'am' COLLATE DATABASE_DEFAULT 
        SELECT 2
    END
    GO
    /*
    Command(s) completed successfully.
    */