やあみんな、私は日時を保持する変数を使用したい動的クエリを使用しています。クエリを実行すると、日時を文字列から変換できないと表示されます。その変数をvarchar(max)
にキャストすると、次のようになります。 datetime
ではなく文字列として送信するので、クエリをどのように実行する必要がありますか。
以下は、実行しようとしているSQLクエリです。
SET @SQL1 = 'SELECT B.FacId, B.FacName, B.BookCode, B.BookName, B.Quantity,
CONVERT(VARCHAR(10), B.TillDate, 104) AS TILLDATE FROM '+@TABLE+' B
WHERE B.TillDate BETWEEN CONVERT(VARCHAR(10),'+@FROMDATE+', 101) and
CONVERT(VARCHAR(10), DATEADD(DD,1,'+@TODATE+'), 101)'
EXEC SP_EXECUTESQL @SQL1
ここに @fromdate
および@todate
は、異なる一時テーブルからのdatetime
タイプです。これらの変数に格納されます。
ここで、このクエリをどのように実行する必要がありますか。すぐに返信してください...
アッバスエレクトリックワーラに感謝します。
日付を引用する必要があります。
SET @SQL1 =
'SELECT B.FacId,
B.FacName,
B.BookCode,
B.BookName,
B.Quantity,
CONVERT(VARCHAR(10), B.TillDate, 104) AS TILLDATE
FROM '+@TABLE+' B
WHERE B.TillDate BETWEEN ''' + CONVERT(VARCHAR(10),@FROMDATE, 101) + ''' and ''' + CONVERT(VARCHAR(10),DATEADD(DD,1,@TODATE), 101) + ''''
このようにパラメータ値を連結しないでください。最善の解決策は、sp_executesqlでパラメーター化されたクエリを使用することです。
_DECLARE @sql nvarchar(4000)
select @sql = N'
SELECT B.FacId
, B.FacName
, B.BookCode
, B.BookName
, B.Quantity
, CONVERT(VARCHAR(10), B.TillDate, 104) AS TILLDATE
FROM ' + quotename(@TABLE) + N' B
WHERE B.TillDate BETWEEN cast(floor(cast(@fromDate as float)) as datetime)
AND cast(floor(cast(@toDate as float)) as datetime)'
EXEC sp_executesql @sql, N'@fromDate datetime, @toDate datetime', @FROMDATE, @TODATE
_
Sp_executesqlについて注意すべき点は次のとおりです。
NVARCHAR
値ですクエリにいくつかの追加の変更が適用されました。
QUOTENAME()
関数でラップされます。convert(,,101)
を実行することはコストのかかる操作であり、キャストを使用してフロートし、その値のフロアを取得することで実行できます。私はこれがうまくいくかもしれないと思います:
DECLARE @tempdate datetime
SET tempdate =DATEADD(DD,1,@TODATE)
SET @SQL1 = 'SELECT B.FacId, B.FacName, B.BookCode, B.BookName, B.Quantity,'''+ cast (B.TillDate as VARCHAR(50))+''' AS TILLDATE FROM '+@TABLE+' B WHERE B.TillDate BETWEEN '''+cast(@FROMDATE as VARCHAR(50))+''' and '''+cast(@tempdate as VARCHAR(50))'''
EXEC SP_EXECUTESQL @SQL1
変数の定義を確認したいのですが、@ FROMDATEと@TODATEが日時であり、文字列連結ステートメントで使用しているためだと思います。したがって、次の方法で修正できます。
SET @SQL1 = 'SELECT B.FacId, B.FacName, B.BookCode, B.BookName, B.Quantity, CONVERT(VARCHAR(10), B.TillDate, 104) AS TILLDATE FROM '+@TABLE+' B WHERE B.TillDate BETWEEN CONVERT(VARCHAR(10),'+CAST(@FROMDATE as varchar(15))+', 101) and CONVERT(VARCHAR(10), DATEADD(DD,1,'+CAST(@TODATE as varchar(15))+'), 101)'
ただし、より良い解決策は次のとおりです。
SET @SQL1 = 'SELECT B.FacId, B.FacName, B.BookCode, B.BookName, B.Quantity, B.TillDate AS TILLDATE FROM '+@TABLE+' B WHERE B.TillDate BETWEEN @inFROMDATE and @inTODATE'
EXEC SP_EXECUTESQL @SQL1,'@inFROMDATE datetime, @inTODATE',@inFromDate = @FROMDATE, @inTODATE = @TODate
この例を実行して、コードに適合させます。 (3つの連続した一重引用符はありません)
Declare @FromDATE datetime
;Declare @ToDATE datetime
;set @FromDATE = getdate()
;set @ToDATE = @FromDATE
;Print 'WHERE TillDate BETWEEN ' + char(39) + CONVERT(VARCHAR(10),@FromDATE, 101)
+ char(39) + ' and ' + char(39) + CONVERT(VARCHAR(10),@ToDATE, 101) + char(39)
これを試して:
declare @sql1 varchar(max)
declare @table sysname
declare @FROMDATE datetime
declare @TODATE datetime
set @table = 'MyTable'
set @FROMDATE = GETDATE()
set @ToDATE = GETDATE()
SET @SQL1 = 'SELECT B.FacId, B.FacName, B.BookCode, B.BookName, B.Quantity,
CONVERT(VARCHAR(10), B.TillDate, 104) AS TILLDATE FROM '+@TABLE+' B
WHERE B.TillDate BETWEEN CONVERT(Datetime,''' + CONVERT(VARCHAR(10),@FROMDATE, 101)
+ ''', 101) and CONVERT(DATETIME,'''+ CONVERT(VARCHAR(10), DATEADD(DD,1,@TODATE), 101) + ''', 101)'
print @sql1
しかし、二重変換を避けるために、ジョエル・マンスフォードの答えを見てください。
これは遅いですが、誰かを助けるかもしれません
あなたが必要とするのはあなたの日付の周りの引用です、あなたはすでにあなたの答えを得ました。
以下は、私が通常クエリに入力するものの例です。
'(CONVERT(DATETIME,CONVERT(varchar,Gd.CreatedDate),106) <= CONVERT(DATETIME,'''+CONVERT(varchar, @EndDate ) +''',106))'
@EndDateのタイプはDatetimeであることに注意してください。