8

Ho creato una procedura con questa struttura, ma non funziona per il parametro di ingresso datetimetipo datetime per il parametro di ingresso nel procedimento

ho eseguito questa domanda ma

declare @a datetime 
declare @b datetime 

set @a='2012/04/06 12:23:45' 
set @b='2012/08/06 21:10:12' 

exec LogProcedure 'AccountLog', N'test', @a, @b 

ma SQL Server mi ha fatto questo error

Conversione non riuscita durante la conversione di data e/o tempo dalla stringa di caratteri.

ma quando prova con questa query funziona

exec LogProcedure 'AccountLog',N'test' 

codice di stored procedure:

alter PROCEDURE LogProcedure 
    @TableName VARCHAR(60), 
    @SearchString NVARCHAR(50), 
    @DateFirst DateTime = '', 
    @DateLast DateTime = '' 
AS 
BEGIN 
    SET NOCOUNT ON 

    DECLARE @FinalSQL  NVARCHAR(MAX) 

    SET @FINALSQL = 'SELECT * FROM [' + @TableName + '] where 1=2 ' 

    IF @DateFirst <> '' and @DateLast <> '' 
     set @FinalSQL = @FinalSQL + ' or convert (Date,DateLog) >=  '''[email protected] + ' and convert (Date,DateLog) <='''[email protected] 

    SELECT 
     @FinalSQL = @FinalSQL + ' or [' + SYSCOLUMNS.NAME + '] LIKE N''%' + @SearchString + '%'' ' 
    FROM SYSCOLUMNS 
    WHERE OBJECT_NAME(id) = @TableName 
    AND TYPE_NAME(SYSCOLUMNS.XTYPE) IN ('VARCHAR','NVARCHAR','CHAR','NCHAR','INT','DECIMAL') 
    ORDER BY COLID 

    EXEC(@FinalSQL) 
END 

Questa query è vero troppo

SELECT * 
FROM AccountLog 
where 1=2 or convert (Date, DateLog) >= '2012/04/06' 
and convert (Date, DateLog) <='2012/08/06' 
+3

Non capisco StackOverflow più, perché questa domanda è stata downvoted? è un problema piuttosto generale con una spiegazione di ciò che ha provato. –

risposta

21

Si dovrebbe usare l'ISO -8601 formato per rappresentazioni di stringa di date - qualsiasi altra cosa dipende dalla lingua di SQL Server e dalle impostazioni di dateformat.

Il formato ISO-8601 per un DATETIME quando si utilizza solo la data è: YYYYMMDD (senza trattini o antyhing!)

Per un DATETIME con la porzione di tempo, è YYYY-MM-DDTHH:MM:SS (con trattini e un T nel parte centrale per separare le parti di data e ora).

Se si desidera convertire una stringa in uno DATE per SQL Server 2008 o successivo, è possibile utilizzare YYYY-MM-DD (con i trattini) per ottenere lo stesso risultato. E non chiedermi perché questo è così incoerente e confuso - lo è, e per ora dovrai lavorare con quello.

Quindi nel tuo caso, si dovrebbe provare:

declare @a datetime 
declare @b datetime 

set @a = '2012-04-06T12:23:45' -- 6th of April, 2012 
set @b = '2012-08-06T21:10:12' -- 6th of August, 2012 

exec LogProcedure 'AccountLog', N'test', @a, @b 

Inoltre - il tuo proc memorizzato ha problema, dal momento che stai concatenare insieme datetime e stringa in una stringa, ma non sei la conversione del datetime a stringa prima, e inoltre, stai dimenticando le virgolette nella tua dichiarazione dopo entrambe le date.

Quindi cambiare questa linea qui per questo:

IF @DateFirst <> '' and @DateLast <> '' 
    SET @FinalSQL = @FinalSQL + ' OR CONVERT(Date, DateLog) >= ''' + 
        CONVERT(VARCHAR(50), @DateFirst, 126) + -- convert @DateFirst to string for concatenation! 
        ''' AND CONVERT(Date, DateLog) <=''' + -- you need closing quotes after @DateFirst! 
        CONVERT(VARCHAR(50), @DateLast, 126) + ''''  -- convert @DateLast to string and also: closing tags after that missing! 

Con queste impostazioni, e una volta che hai risolto il tuo stored procedure che contiene problemi in questo momento, funzionerà.

1

In questa parte del vostro SP:

IF @DateFirst <> '' and @DateLast <> '' 
    set @FinalSQL = @FinalSQL 
     + ' or convert (Date,DateLog) >=  ''' + @DateFirst 
     + ' and convert (Date,DateLog) <=''' + @DateLast 

si sta tentando di concatenare le stringhe e datetimes.

Come tipo datetime ha priorità maggiore rispetto varchar/nvarchar, l'operatore +, quando avviene tra una stringa e un datetime, viene interpretato come Inoltre, non come concatenazione, e il motore poi cerca di convertire le parti degli archi (' or convert (Date,DateLog) >= ''' e altri) a datetime o valori numerici. E fallisce.

Ciò non accade se si omettono gli ultimi due parametri quando si richiama la procedura, poiché la condizione restituisce false e l'istruzione non valida non viene eseguita.

Per modificare la situazione, è necessario aggiungere fusione esplicita delle variabili datetime in stringhe:

set @FinalSQL = @FinalSQL 
    + ' or convert (Date,DateLog) >=  ''' + convert(date, @DateFirst) 
    + ' and convert (Date,DateLog) <=''' + convert(date, @DateLast) 

avrete anche bisogno di aggiungere chiusura virgolette singole:

set @FinalSQL = @FinalSQL 
    + ' or convert (Date,DateLog) >=  ''' + convert(date, @DateFirst) + '''' 
    + ' and convert (Date,DateLog) <=''' + convert(date, @DateLast) + '''' 
Problemi correlati