it-swarm-id.com

Bagaimana cara memasukkan parameter datetime dalam prosedur tersimpan bersama dengan kueri string?

Prosedur tersimpan saya adalah sebagai berikut,

    -- Add the parameters for the stored procedure here 
   @FromDate datetime,
   @ToDate datetime

       --Select query
      DECLARE @query nvarchar(max)

      set @query='SELECT [col1] 
                  FROM [Table1]              
                  WHERE ([col2] BETWEEN '''[email protected]+''' AND'''[email protected]+''')'

       execute sp_executesql @query

Menjalankan permintaan string ini menghasilkan kesalahan berikut,

"Konversi gagal saat mengonversi tanggal dan/atau waktu dari string karakter."

Siapa saja tolong bantu saya untuk menyelesaikan masalah ini ...

5
Harun

Masalah mendasar adalah bahwa TSQL tidak dapat secara implisit mengubah datetime (atau integer atau floating point) menjadi tipe data karakter. Ini benar-benar berjalan mundur, ia mencoba untuk secara implisit mengkonversi data karakter ke datetime (int/floating point value) berdasarkan pada aturan diutamakan tipe data. Omong-omong, inilah pesan kesalahan Anda yang memberi tahu Anda, itu tidak bisa mengonversi string ke nilai datetime. Anda harus secara eksplisit memintanya untuk menggabungkan nilai ke dalam string karakter.

Contoh ini menunjukkan kepala sekolah dengan bilangan bulat karena mereka lebih mudah untuk memahami nilai yang diharapkan.

DECLARE 
    @stringInt nvarchar(3)
,   @intint int

SELECT
    @stringInt = N'3'
,   @intint = 5

SELECT 
    @stringInt + @intint AS implicit_conversion
,   @stringInt + CAST(@intint AS nvarchar(5)) AS explicit_conversion

Nilai konversi implisit menunjukkan @stringint dikonversi menjadi integer terlebih dahulu dan kemudian + diperlakukan sebagai penambahan numerik dan menghasilkan 8. Konversi eksplisit @intint ke tipe data karakter menghasilkan tanda + diperlakukan sebagai gabungan dengan string dikembalikan 35

implicit_conversion explicit_conversion
------------------- -------------------
8                   35

Untuk mengatasi masalah yang disediakan, Anda harus secara eksplisit memasukkan nilai datetime Anda ke tipe karakter sehingga string kueri dapat digabungkan sesuai yang diharapkan.

set @query='SELECT [col1] 
FROM [Table1]              
WHERE ([col2] BETWEEN ''' + CONVERT(nvarchar(24), @FromDate, 121) +''' AND'''+ CONVERT(nvarchar(24), @ToDate, 121) +''')'

Tetapi seperti yang ditunjukkan di atas, Anda benar-benar tidak ingin melakukan itu karena sejumlah alasan, SQL Injection menjadi salah satunya. Ini juga membuat pemeliharaan Anda lebih sulit ketika Anda mengiris dan mencelupkan string kueri dalam TSQL.

Pendekatan yang lebih baik adalah membuat parameter permintaan Anda dan menggunakan kekuatan sp_executesql . Yang menyenangkan tentang parameter sp_executesql adalah Anda tidak harus menggunakan semua parameter yang disediakan. Bergantung pada apa yang benar-benar Anda coba lakukan, ini mungkin bermanfaat.

Tabel sampel dan data

CREATE TABLE 
dbo.table1
(col1 int, col2 datetime)

INSERT INTO
    dbo.table1
SELECT
3, '2009-04-06'
UNION ALL SELECT
1, '2001-09-11'

Demo menggunakan parameter

DECLARE
    @FromDate datetime,
    @ToDate datetime

SELECT    
    @FromDate = '2005-03-17'
,   @ToDate = current_timestamp

DECLARE
    @query nvarchar(max)
SET @query = N'    
SELECT [col1] 
FROM [Table1]              
WHERE ([col2] BETWEEN @start AND @end)'

-- gratuitous use of parameter assignment here
-- could just as easily used @FromDate and @ToDate
-- in the @query and the parameter list
EXECUTE sp_executesql 
    @query
,   N'@start datetime, @end datetime'
,   @start = @FromDate
,   @end = @ToDate

Hasil

col1
3
11
billinkc

Untuk menghindari kesalahan ini, dan kerentanan SQL Injection, Anda harus menulis ulang kueri Anda sebagai berikut:

@FromDate datetime,
@ToDate datetime

--Select query
 SELECT [col1] 
   FROM [Table1]              
  WHERE [col2] BETWEEN @FromDate AND @ToDate
3
datagod