Conversion failed when converting date and/or time from character string? - sql-server

So, I need to show the consumption of the material on the current month and the last 6 too. I'm trying to put an alias name on the columns with the respective month just like "MM/YY".
Example of the columns: 08/17 | 07/17 | 06/17 | ... | 02/17
DECLARE #mes_atual DATE; SET #mes_atual = CAST(FORMAT(GETDATE(),'MM/YY') AS DATE)
DECLARE #mes1 DATE; SET #mes1 = DATEADD(MM, -1, #mes_atual); SET #mes1 = CAST(#mes1 AS VARCHAR)
DECLARE #mes2 DATE; SET #mes2 = DATEADD(MM, -2, #mes_atual); SET #mes2 = CAST(#mes2 AS VARCHAR)
DECLARE #mes3 DATE; SET #mes3 = DATEADD(MM, -3, #mes_atual); SET #mes3 = CAST(#mes3 AS VARCHAR)
DECLARE #mes4 DATE; SET #mes4 = DATEADD(MM, -4, #mes_atual); SET #mes4 = CAST(#mes4 AS VARCHAR)
DECLARE #mes5 DATE; SET #mes5 = DATEADD(MM, -5, #mes_atual); SET #mes5 = CAST(#mes5 AS VARCHAR)
DECLARE #mes6 DATE; SET #mes6 = DATEADD(MM, -6, #mes_atual); SET #mes6 = CAST(#mes6 AS VARCHAR)
SET #mes_atual = CAST(#mes_atual AS VARCHAR)
DECLARE #query VARCHAR;
DECLARE #selects VARCHAR;
SET #selects = 'QT_CONS_MES_ATUAL AS [' + CAST(#mes_atual AS VARCHAR) + '], QT_CONS_MES_1 AS [' + CAST(#mes1 AS VARCHAR) + '], QT_CONS_MES_2 AS [' + CAST(#mes2 AS VARCHAR) + '], QT_CONS_MES_3 AS [' + CAST(#mes3 AS VARCHAR) + '], QT_CONS_MES_4 AS [' + CAST(#mes4 AS VARCHAR) + '], QT_CONS_MES_5 AS [' + CAST(#mes5 AS VARCHAR) + '], QT_CONS_MES_6 AS [' + CAST(#mes6 AS VARCHAR) + ']'
SET #query = 'SELECT [VERSAO]
,[IN_TP_DISP]
,[CD_OWNER]
,[DS_OWNER]
,[OP_ITEM_PROD]
,[DS_PRODUTO]
,[CD_MAT_GRUPO]
,[CD_MAT_SUBGRUPO]
,[CD_MAT_CLASSE]
,[CD_MAT_NIVEL4]
,[CD_MAT_NIVEL5]
,[CD_UNMED_EST]
,[CD_DIVISAO]
,[IN_CTR_DISP]
,[IN_TIPO_REPOS]
,[QT_ETQ_MAXIMO]
,[QT_ETQ_MINIMO]
,[QT_LOTE_COMPRA]
,[QT_SALDO_ATUAL]
,[VL_SALDO_ATUAL]
,[QT_SALDO_RES]
,[QT_SALDO_ENC]
,[QT_SALDO_DISP]
,'+#selects+'
,[SQ_MOVTO]
,[QT_SALDO_CUR]
,[QT_SALDO_BENTO]
,[QT_SALDO_BAURU]
,[CD_FOR_ITEM]
,[VL_CUSTO_ULT_COMPRA]
,[CD_PESSOA_FORN]
,[NOME_FORN]
,[AN_NFE]
,[DT_ENTRADA]
,[AN_PC]
FROM [dbo].[VW_SQL_CONSUMO_BI]'
EXEC(#query)
I'm trying to put the alias name of some columns with a dinamic date but when I convert the date to a VARCHAR data, build the query and exec it i get the error:
Mensagem 241, NĂ­vel 16, Estado 1, Linha 3
Conversion failed when converting date and/or time from character string.
Ps: The error message is in portuguese but I hope u guys can help me.

The problem is your variable at the very top. How can a month and year be a date? You need a day. Get rid of that silly cast/format stuff and just set your date to getdate.
DECLARE #mes_atual DATE; SET #mes_atual = GETDATE()
select #mes_atual

you cannot create a valid date without a day
So put GetDate in your variable and use Format to only show the year and month
DECLARE #mes_atual DATE
SET #mes_atual = GetDate()
select #mes_atual as mes_atual,
FORMAT(#mes_atual,'MM/yy') AS date
this returns
mes_atual date
2017-08-04 08/17

Don't Cast as Date. Just use the formatting to get what you want.
Notice the yy is lowercase
Select FORMAT(#mes_atual,'MM/yy')
DECLARE #mes_atual DATE; SET #mes_atual = GETDATE()
Select #mes_atual
Select FORMAT(#mes_atual,'MM/yy')
Will render
2017-08-04
08/17

Related

Print a sentence saying the day of the year using SQL Server

I am trying to write this using SQL SERVER:
"Hi! Today is ... This is the day number... of the year. New year's eve is in ... days".
My code runs with no problem but I can't print as well. What am I doing wrong? I haven't finished the whole phrase because I need to fix the problem before I get to the last part.
DECLARE
#currentDate DateTime
SET #currentDate = GETDATE();
DECLARE #dayofyear datetime
SET #dayofyear=DATEDIFF(day,STR(YEAR(#dayofyear),4)+'0101',#dayofyear)+1
-- SELECT Numbertoday = DATEDIFF(day,STR(YEAR(#dayofyear),4)+'0101',#dayofyear)+1
print('Hi! Today is '+ CONVERT(VARCHAR(10), #currentDate , 111) + '. ' + 'This is the day number '+ ' ' + CONVERT (VARCHAR(10), #dayofyear) + of the year.')
Another way to do is:
declare #today varchar(11) = convert(varchar(11), getdate(), 1);
declare #dayOfTheYear int = datepart(DAYOFYEAR, getdate());
declare #untilNewYearsEve int = datepart(dayofyear, datefromparts(year(getdate()), 12, 31)) - #dayOfTheYear
-- if you use print, you should see the result under the 'messages' tab not in the 'results' tab in SSMS
print 'Hi! Today is '+ #today + '. ' + 'This is the day number '+ cast( #dayOfTheYear as varchar(3)) + '. New year''s eve is in '+
cast (#untilNewYearsEve as varchar(3)) + ' days.'
This should work perfectly fine.
while seeting the day of year you need to put #current date so it will work because you are trying to get a day from a #currentdate
DECLARE
#currentDate DateTime
SET #currentDate = GETDATE();
DECLARE #dayofyear datetime
SET #dayofyear=DATEDIFF(day,STR(YEAR(#currentDate),4)+'0101',#currentDate)+1
print('Hi! Today is '+ CONVERT(VARCHAR(10), #currentDate , 111) + '. ' + 'This is the day number '+ ' ' + CONVERT (VARCHAR(10), #dayofyear) + 'of the year.')
Just for fun, you can use concat()
Example
Print concat('Hi! Today is '
,format(GetDate(),'dddd, MMM d, yyyy.')
,' This is the day number '
,DateDiff(DAY,datename(YEAR,getdate())+'0101',getdate()) + 1
,' of the year.'
)
Results
Hi! Today is Thursday, Jul 4, 2019. This is the day number 185 of the year.
You can simplify things a bit using DAYOFYEAR parameter in the DATEPART function if using SQL 2008 and above. And you don't really need to declare a variable for the date.
Sample Code:
print('Hi! Today is '+ convert(varchar(10), getdate() , 111) + '. ' + 'This is the day number' + ' ' + convert(varchar, datepart(dayofyear, getdate()))) + ' of the year.'
Results:
Hi! Today is 2019/07/05. This is the day number 186 of the year.

How to convert/cast column data type in concatenated SQL query string

i have the following variables defined in my stored procedure
#StartDate DateTime,
#EndDate DateTime,
I'm setting the sql to be executed dynamically, so when constructing the query where clause i have the below line.
SET #sql = #sql + ' AND (convert(datetime, R.ReportDate, 121) >= ' + #StartDate + 'AND convert(datetime, R.ReportDate, 121) <=' + #EndDate +')'
When i execute the stored procedure, the line above throws the error below
Conversion failed when converting datetime from character string.
If i change the variable datatype to NVARCHAR(MAX), the procedure executes successfully but then returns no rows because the date comparison/matching fails.
ReportDate column is of datatype datetime and has data in this format 2014-06-01 00:00:00.000
As you can see i have tried converting the column when constructing my query but that isn't working.
The problem is not with ReportDate, but when you are trying to concatenate your DateTime parameters with your nvarchar sql statement. The problem can be reproduced fairly simply with:
DECLARE #SQL NVARCHAR(MAX) = 'Some text' + GETDATE();
The wrong way to fix this is to convert the datetime parameter to a string so that it can be concatenated with a string, e.g.
SET #sql = #sql + ' AND r.ReportDate >= CONVERT(DATETIME, '''
+ CONVERT(VARCHAR(10), #StartDate, 112)
+ ''', 112) AND r.ReportDate <= CONVERT(DATETIME, ''' +
+ CONVERT(VARCHAR(10), #EndDate, 112)
+ ''', 112)';
N.B. I am including this for completeness of the answer, and in no way endorse this approach
The correct way to fix this is to use sp_executesql and pass properly typed parameters this way, this will avoid conversion issues. e.g.
SET #sql = #sql + 'AND r.ReportDate >= #StartDateParam AND r.ReportDate <= #EndDateParam';
EXECUTE sp_executesql
#sql,
N'#StartDateParam DATETIME, #EndDateParam DATETIME',
#StartDateParam = #StartDate,
#EndDateParam = #EndDate

The data types varchar(max) and date are incompatible in the add operator

I have created one of the search SP here, Just preparing parameters based on user input on screen.
Now I need to cast the table column as well as input parameter with DATE type and then need to query.
Below is the part of the procedure which I need to achieve.
Problem is, I'm getting the following error now:
The data types varchar(max) and date are incompatible in the add operator.
DECLARE #WhereClause VARCHAR(MAX)
DECLARE #DateField DATETIME = GETDATE()
DECLARE #DateFieldTo DATETIME = GETDATE() +1
SET #WhereClause = #WhereClause + ' AND CAST(tbl.DateField AS DATE) BETWEEN ''' + CAST(#DateField AS DATE) + ''' + AND ''' + CAST(#DateFieldTo AS DATE)+ ''
PRINT #WhereClause
I tried the below approach:
DECLARE #WhereClause VARCHAR(MAX)
DECLARE #DateField DATETIME = GETDATE()
DECLARE #DateFieldTo DATETIME = GETDATE() +1
DECLARE #YourSQLVariable VARCHAR(MAX)
SET #WhereClause = #WhereClause + ' AND CAST(tbl.DateField AS DATE) BETWEEN CAST(#DateField AS DATE) + AND CAST(#DateFieldTo AS DATE)'
SET #YourSQLVariable = 'SELECT 1 WHERE' + #WhereClause
EXEC sp_executeSQL #YourSQLVariable,N'#DateField DATETIME,#DateFieldTo DATETIME ',#DateField,#DateFieldTo
And got:
Error: Procedure expects parameter '#statement' of type 'ntext/nchar/nvarchar'.
It's because you are trying to concatenate a DATE type CAST(tbl.DateField AS DATE) with a string #WhereClause, which is not supported, in this line:
SET #WhereClause = #WhereClause + ' AND CAST(tbl.DateField AS DATE) BETWEEN ''' + CAST(#DateField AS DATE) + ''' + AND ''' + CAST(#DateFieldTo AS DATE)+ ''
You can achieve this using something like this:
SET #WhereClause = #WhereClause + ' AND CAST(tbl.DateField AS DATE) BETWEEN CAST(#DateField AS DATE) + AND CAST(#DateFieldTo AS DATE)'
and when running sp_executeSQL, use this:
#YourSQLVariable = #SelectClause + #WhereClause
EXEC sp_executeSQL #YourSQLVariable,N'#DateField DATETIME,#DateFieldTo DATETIME ',#DateField,#DateFieldTo
You can try this for date casting or date comparison only w.r.t date,
DECLARE #SqlQuery VARCHAR(MAX) = ''
DECLARE #UserId VARCHAR(MAX) = 'TestUser'
DECLARE #StartDate DATETIME = GETDATE()
DECLARE #EndDate DATETIME = DATEADD(WEEK, -6, GETDATE())
SET #SqlQuery = 'SELECT * FROM User Z WHERE Z.Id = ''' + #UserId + ''' AND CAST(Z.CreatedDate AS DATE) BETWEEN CAST(''' + CONVERT(NVARCHAR(24), #StartDate, 101) + ''' AS DATE) AND CAST(''' + CONVERT(NVARCHAR(24), #ENDDATE, 101) +''' AS DATE)'
You can't concatenate date objects with strings:
DECLARE #WhereClause VARCHAR(MAX)
DECLARE #DateField DATETIME = GETDATE()
DECLARE #DateFieldTo DATETIME = GETDATE() +1
SET #WhereClause = #WhereClause + ' AND CONVERT(VARCHAR(10),tbl.DateField,120) BETWEEN ''' + CONVERT(VARCHAR(10),#DateField,120) + ''' + AND ''' + CONVERT(VARCHAR(10),#DateFieldTo,120)+ ''''
PRINT #WhereClause
SQL does not allow strings to be concatenated with other data types.
DECLARE #WhereClause VARCHAR(MAX) = ''
DECLARE #DateField DATETIME = GETDATE()
DECLARE #DateFieldTo DATETIME = GETDATE() +1
SET #WhereClause = #WhereClause + ' AND CAST(tbl.DateField AS DATE) BETWEEN ''' + CONVERT(VARCHAR(25), #DateField, 120) + ''' AND ''' + CONVERT(VARCHAR(25), #DateFieldTo, 120) + ''''
PRINT #WhereClause
Also, the #WhereClause was not defined, so the concatenation was not working with the initial null string.

Error in Customized Procedure "Must declare the scalar variable #startdate"

I have a procedure to fetch data as per the criteria passed. I works fine with #month, #year, #quater.
ALTER PROCEDURE dbo.SPReportTimeSpan
(
#Week int = null,
#Month int = null,
#Year int = null,
#Quater int = null
)
AS
SET NOCOUNT ON
DECLARE #sql nvarchar(4000)
If (#Week) IS NOT NULL
BEGIN
DECLARE #startdate Date, #enddate Date
EXEC dbo.SPReturnStartEndDateOfSpecifiedWeek #Week, #startdate OUTPUT, #enddate OUTPUT
SELECT #startdate, #enddate
END
SELECT #sql='SELECT
CRMDR.Id as Id,.
CRMDR.Request_For_Id as Request_For_Id
From [CRM].[dbo].[CRM_Doctor_Request] AS CRMDR
WHERE CRMDR.Is_Deleted=0 '
If (#Month) IS NOT NULL
SELECT #sql=#sql + ' AND MONTH(CRMDR.Date_Created) like (#Month) '
If (#Year) IS NOT NULL
SELECT #sql=#sql + ' AND YEAR(CRMDR.Date_Created) like (#Year) '
If (#Week) IS NOT NULL
SELECT #sql=#sql + ' AND (CRMDR.Date_Created) BETWEEN (#startdate) AND (#enddate) '
If (#Quater) IS NOT NULL
IF (#Quater = 1)
SELECT #sql=#sql + ' AND MONTH(CRMDR.Date_Created) in (4,5,6) '
IF (#Quater = 2)
SELECT #sql=#sql + ' AND MONTH(CRMDR.Date_Created) in (7,8,9) '
IF (#Quater = 3)
SELECT #sql=#sql + ' AND MONTH(CRMDR.Date_Created) in (10,11,12) '
IF (#Quater = 4)
SELECT #sql=#sql + ' AND MONTH(CRMDR.Date_Created) in (1,2,3) '
SELECT #sql=#sql + ' ORDER BY CRMDR.Id DESC '
EXEC sp_executesql #sql, N'#Month int, #Year int, #Quater int',
#Month, #Year, #Quater
RETURN
But for #week it gives error.
Running [dbo].[SPReportTimeSpan] ( #Week = 3, #Month = <NULL>, #Year = <NULL>, #Quater = <NULL> ).
Must declare the scalar variable "#startdate".
Column1 Column2
------------------------------ ------------------------------
2013-02-10 00:00:00.0000000 2013-02-17 00:00:00.0000000
No rows affected.
(1 row(s) returned)
#RETURN_VALUE = 0
Finished running [dbo].[SPReportTimeSpan].
I am not getting why its not working with week criteria. Please help if anyone have idea.
#startdate and #enddate are only accessible within the scope of your IF statement:
If (#Week) IS NOT NULL
BEGIN
DECLARE #startdate Date, #enddate Date
EXEC dbo.SPReturnStartEndDateOfSpecifiedWeek #Week, #startdate OUTPUT, #enddate OUTPUT
SELECT #startdate, #enddate
END
Move the declaration outside of the IF statement if you wish to reference these variables elsewhere:
DECLARE #startdate Date, #enddate Date
If (#Week) IS NOT NULL
BEGIN
EXEC dbo.SPReturnStartEndDateOfSpecifiedWeek #Week, #startdate OUTPUT, #enddate OUTPUT
SELECT #startdate, #enddate
END
FYI: The area where you make reference to these variables outside of the IF statement is here:
If (#Week) IS NOT NULL
SELECT #sql=#sql + ' AND (CRMDR.Date_Created) BETWEEN (#startdate) AND (#enddate) '
I got solution of my problem. To solve the problem, I need to explicitly cast datetime values to a character type so the query string can be concatenated as expected.
If (#Week) IS NOT NULL
SELECT #sql=#sql + ' AND (CRMDR.Date_Created) BETWEEN ''' + convert(VARCHAR,#startdate) + ''' AND ''' +convert(VARCHAR,#enddate) + ''''
or this (More Optimized)
SELECT #sql=#sql + ' AND (CRMDR.Date_Created BETWEEN #startdate AND #enddate)'
which needs to add something to sp_executesql
EXEC sp_executesql #sql, N'#Month int, #Year int, #Quater int, #Week int, #startdate datetime, #enddate datetime ',
#Month, #Year, #Quater, #Week, #startdate, #enddate
Your variables are out of scope.

sql stored procedure execute command

I've created the following stored procedure on sql:
CREATE PROCEDURE Sp_generate_report (#YEAR INT,
#MONTH INT)
AS
DECLARE #CATEGORY VARCHAR(20)
DECLARE #BEGIN_DATE DATE
DECLARE #END_DATE DATE
BEGIN
SELECT #BEGIN_DATE = Cast(( Cast(#YEAR AS VARCHAR) + '-'
+ Cast(#MONTH AS VARCHAR) + '-' + '1' ) AS DATE)
SELECT #END_DATE = Cast(( Cast(#YEAR AS VARCHAR) + '-' +
Cast(#MONTH AS VARCHAR) + '-' + '32' ) AS DATE)
SELECT TOP 1 #CATEGORY = Name
FROM dbo.Profitible_categories(#BEGIN_DATE, #END_DATE)
INSERT INTO dbo.MONTHLY_SUMMARY_REPORTS
VALUES (#CATEGORY)
END
The procedure was created successfully, but when I try to execute it with the following command:
EXECUTE SP_GENERATE_REPORT 2012, 7
I get this error message:
Msg 241, Level 16, State 1, Procedure SP_GENERATE_REPORT, Line 8
Conversion failed when converting date and/or time from character
string.
thanks in advance for the help.
You can calculate the last day of the month without all that nasty string concatenation or trying to guess which month it is and pick the last day.
CREATE PROCEDURE dbo.Sp_generate_report
#YEAR INT,
#MONTH INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #BEGIN_DATE DATE = DATEADD(MONTH, #MONTH-1, CONVERT(DATE,
CONVERT(CHAR(4), YEAR) + '0101'));
DECLARE #END_DATE DATE = DATEADD(DAY, -1, DATEADD(MONTH, 1, #BEGIN_DATE));
INSERT INTO dbo.MONTHLY_SUMMARY_REPORTS
SELECT TOP (1) Name
FROM dbo.Profitible_categories(#BEGIN_DATE, #END_DATE);
END
GO

Resources