2017-06-07 18 views
0

にSMALLDATETIMEへの変換以下の動的SQLはエラーをスロー:SQL Serverの - 動的SQLステートメント

The conversion failed when converting character string to smalldatetime data type

マイコード:

DECLARE @pTimeStamp smalldatetime 
SET @pTimeStamp = '2017-05-22 12:15:00' 

DECLARE @SQLQuery AS NVARCHAR(4000) 
Set @SQLQuery = N'Select *' + 
' From SampleTable' + 
' Where TimeStamp = ' + @pTimeStamp 

EXECUTE sp_executesql @SQLQuery 

私も

Convert(smalldatetime, @pTimeStamp, 20) 

を試してみました同様に

CAST(@pTimeStamp AS smalldatetime) 

しかし、私は他のエラーが発生します。私は@pTimeStampvarchar(50)と宣言してみましたが、変換してもまだエラーがありました。

DECLARE @pTimeStamp smalldatetime 
SET @pTimeStamp = '2012-01-22 12:15:00' 

Select * 
From SampleTable 
Where TimeStamp = @pTimeStamp 

ので、私はそれは、動的SQLに関係している推測している細かい走っ:のような単純な何かをして

助けてください

+0

私はTHIのような問題が発生したときはいつでも■自分のコードにデバッグ用のPRINTを追加して、ダイナミックSQLの外観を確認します。 –

+0

なぜあなたはそのような質問を書いていますか?なぜパラメータ化クエリを使用しないのですか? –

+1

なぜここで動的SQLを使用していますか?あなたが投稿したものから、ダイナミックなSQLはまったく必要ありません。それを行う場合は、パラメータ化する必要があります。 –

答えて

2

ザ・唯一の真の安全なフォーマット、少なくともdatetimesmalldatetimeのために、以下のとおりです。YYYYMMDDYYYY-MM-DDThh:mm:ss[.nnn] - Bad habits to kick : mis-handling date/range queries - Aaron Bertrand

あなたは既にsp_executesqlを使用して、なぜされていませんそのパラメータを利用しますか?

declare @pTimeStamp smalldatetime; 
declare @params nvarchar(4000); 
declare @sqlquery nvarchar(4000); 

set @pTimeStamp = '2017-05-22T12:15:00'; 
set @params = N'@pTimeStamp smalldatetime'; 
set @sqlquery = N' 
select * 
from SampleTable 
where TimeStamp = @pTimeStamp'; 

execute sp_executesql @sqlquery, @params, @pTimeStamp; 

rextesterデモ:http://rextester.com/FVC44260


動的SQL参照:

+0

ユーレカ!ありがとうございますSqlZim ....特にサンプルコードです。パラメータ化されたクエリを調べるだけでは困難になりましたが、あなたのコードは完全に理解できました。値の真ん中の「T」は私にそれを持たないために記憶された値として混乱させ、私はそれをSPの自分のパラメータに含めなかった。私はそれが私の検索で使用されているのを見て、それが何のために使用されているのか把握しようとします。再度、感謝します! –

+0

@TiltingCodeお手伝いをお待ちしています!関連記事を読むと、 'T 'が何をしているのかが説明されています。 [蹴る悪い習慣:誤った日付/範囲のクエリ - Aaron Bertrand](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/16/bad-habits-to-kick-mishandling-date- range-queries.aspx)。 - 基本的に、 'T'を指定すると、言語設定にかかわらずリテラルはISO形式として認識されます。 – SqlZim

0

タイムスタンプを一重引用符で埋め込む必要があります。試してみてください:SQL Serverの日付/時刻リテラルの

Set @SQLQuery = N'Select *' + 
' From SampleTable' + 
' Where TimeStamp = ''' + @pTimeStamp + '''' 
+3

それは悪い考えです。 OPは、文字列連結の代わりに*パラメータ*を使用する必要はありません。これはSQLインジェクション攻撃を可能にするだけでなく、変換と解析の問題にもつながります。正しいクエリを書くのがずっと簡単です –

+0

@PanagiotisKanavos Bad?必ずしも。 '@pTimeStamp'変数の型は' smalldatetime'です。 SQLインジェクションの機会はありません。ステートメント*は実行されるたびに再コンパイルする必要があります。もう何か持っていますか? –

+1

実際にはい。まず、それが実際のステートメントであれば、動的SQLを使用する必要はありません。パラメータが別のソースから来た場合、注入エラーと変換エラーの両方が可能です。パラメータ化の利点が失われ、冗長な実行計画が生成されます。引用符を追加することで、不正なクエリを修正することはできません。正しいクエリを書くことは、より簡単で、速く、より安全です。なぜ* bad *クエリを隠すのでしょうか? –

関連する問題