2

私は奇妙な行動を観察しています。to の部分文字列の変換に関連する次のコードは正常nvarchartinyint動作します。

DECLARE @s nvarchar(50) = N'Line 1'
DECLARE @n tinyint = SUBSTRING(@s, 6, 10)

SELECT
        N'Line 1' AS explicit_nvarchar,
        @s AS nvarchar_variable,
        SUBSTRING(@s, 6, 10) AS nvarchar_substring
        , @n AS tinyint_var_converted_earlier
        , CAST(SUBSTRING(@s, 6, 10) AS tinyint) AS cast_sub_var
        , CAST(SUBSTRING(N'Line 1', 6, 10) AS tinyint) AS cast_nvarchar_substr

Microsoft SQL Server Management Studio で次の出力を確認できます。

ここに画像の説明を入力.

SELECTただし、コメント行のコメントが解除されている場合、表からの操作を試みるコードは失敗します。

Select 
    [order].[identifier] As [order_identifier],
    [plan_data].[starts_on] As [from],
    [plan_data].[ends_on] As [to],
    [workplace].[identifier] AS line_identifier,
    SUBSTRING([workplace].[identifier], 6, 10) AS line_no_str
    --, CAST(SUBSTRING([workplace].[identifier], 6, 10) AS int) AS line_no
From 
    ...

コメント行で... ここに画像の説明を入力

tinyintしかし、コメントされていない行で(またはへの変換のための両方int)...

ここに画像の説明を入力

更新:奇妙です。すべての行に含まれているかどうかを確認するために、WHERE に最後の行を追加しました。'Line...

Where
    [plan].[identifier] = @lPlanIdentifier And
    (
        [plan_data].[starts_on] Between @fromUTC And @toUTC Or
        [plan_data].[ends_on] Between @fromUTC And @toUTC)
    AND LEFT([workplace].[identifier], 4) = N'Line'

...そして突然、コメントのない行でも機能します。問題の原因を特定するにはどうすればよいですか?

Update2: Hamlet Hakobyan の回答が公開されたとおりに正確に従うべきでした。テーブルの中を見ると、次のことがわかります。

ここに画像の説明を入力

4

3 に答える 3

4

を返すidentifier列に値があります。SUBSTRING([workplace].[identifier], 6, 10)ined

このクエリを試してください:

SELECT * FROM [workplace]
WHERE SUBSTRING([identifier], 6, 10) = N'ined'
于 2013-01-22T21:53:42.930 に答える
1

varcharを数値に変換するときにエラーが発生した場合は、データを見つける最も簡単な方法はを使用することIsNumericです。ただし、この回答でG Mastrosが説明しているように、科学形式または10進数形式を削除する価値があるIsNumericという意味ではありません。IsInteger

SELECT
    [order].[identifier] As [order_identifier],
    [plan_data].[starts_on] As [from],
    [plan_data].[ends_on] As [to],
    [workplace].[identifier] AS line_identifier,
    SUBSTRING([workplace].[identifier], 6, 10) AS line_no_str
    --, CAST(SUBSTRING([workplace].[identifier], 6, 10) AS int) AS line_no
FROM
  ...

WHERE 

   IsNumeric(SUBSTRING([workplace].[identifier], 6, 10) + '.0e0') = 0

修正できないが、デフォルト値を使用できる場合は、caseステートメントを使用して、合法的な場合にのみ変換を実行できます。

SELECT
    [order].[identifier] As [order_identifier],
    [plan_data].[starts_on] As [from],
    [plan_data].[ends_on] As [to],
    [workplace].[identifier] AS line_identifier,
    CASE WHEN IsNumeric(SUBSTRING([workplace].[identifier], 6, 10) + '.0e0') = 1
             THEN CAST(SUBSTRING([workplace].[identifier], 6, 10) AS int) 
             ELSE Null --Default to null in this example
    END as line_no
于 2013-01-22T22:22:11.240 に答える
1

コメントやその他の回答で示されているように、[workplace].[identifier]にキャストできない1つ以上の行の値がありINTます。句に以下を追加すると、WHERE句で変換される前に、このデータを含む行が削除されましたSELECT

LEFT([workplace].[identifier], 4) = N'Line'

次のコマンドを実行して、の値の個別のリストを取得します[workplace].[identifier]

SELECT DISTINCT [workplace].[identifier]
FROM [workplace]
于 2013-01-22T22:19:29.960 に答える