2017-07-09 26 views
1

私はREXTESTERを使用してSQL Serverコードを記述しています。照合の競合SQL Serverのvarcharストアドプロシージャのパラメータ

それはここでメッセージを引き起こす最小限のコードだそれは...

を使われている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ません - 何の問題

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

答えて

2

サーバー/データベース/列の照合順序が異なる値(おそらく、サーバーおよびデータベース)を持っているので、これが発生します。あなたは明示的に照合して追加することによって、それを修正することができます:

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 SQL_Latin1_General_CP1_CI_AS ; 
    SELECT 2; 
END; 

私は、これは共通の列ではないことを認めています。自分のシステムでは、デフォルトの照合順序はおそらくすべて一致します。 Rextesterのデザイナーが異なるデフォルトの照合順序を持つ理由はわかりません。

+0

ありがとうございます。それは治療に役立ちます。しかし、それほど直感的ではありません。奇妙なよ、宣言ではなく、IFでそれをやるよ。特に複数のIFがある場合は特に! – JGFMK

+1

@ JGFMK。 。 。それは 'if'にはない。それは定数です。私は定数を作ることは、記憶されたデータがより賢明であるのと同じ照合をしていることを示しています。しかし、私が考えているように、定数は変数宣言から異なる照合を得るのは不思議です。私がこれについてあまりにも難しいと思うのは早すぎます。 –

+0

あああ...私は 'pm'リテラルでも必要なので... – JGFMK

1

もう1つの解決策(ゴードンの解決策+1)は、COLLATE DATABASE_DEFAULTを使用することです。これは、現在のデータベースの照合を意味します。次の例は、以下の照合に基づいています。現在のためにtempdbデータベース

  • 'Romanian_CI_AS' の

    1. 'Latin1_General_CI_AS' - DbCollat​​eDiffThanTempDbCollat​​ - データベース。

    CREATE PROCEDURE #...ステートメントがCOLLATE DATABASE_DEFAULTオプションでDbCollateDiffThanTempDbCollatデータベースのコンテキスト内で実行されるので、これはIF @AMPM = 'am' COLLATE DATABASE_DEFAULT(この文脈で)IF @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. 
    */ 
    
  • 関連する問題