I have an existing sql server stored procedure, that I'm trying to update. Every time I run Alter Procedure on it, I get the following error:
SQL Error: Must declare the scalar variable "#varOne".
I've Googled around but nothing that I can find helps out with how to get past this error... :/ Procedure below:
ALTER PROCEDURE [dbo].[sp_test] (
-- Declare
#varOne tinyint,
#varTwo numeric(17,0)
) As
Set NoCount On
-- Select
Select *
Into #t
From SQL_Test.dbo.trans with (nolock)
Where test>=123
And Case #varOne When 1 Then rNo When 2 Then iNo When 3 Then sNo End = #varTwo
Union
Select *
From SQL_Test.dbo.trsave with (nolock)
Where date_time > DateAdd(dd, -60, GetDate())
And Case #varOne When 1 Then rNo When 2 Then iNo When 3 Then sNo End = #varTwo
EDIT: I solved the problem by dropping the original procedure, and recreating it. Still curious why the alter would not work. Guessing it is caused by the client using SQL Server 2012.
I solved the problem by dropping the original procedure, and recreating it. Still curious why the alter would not work. Guessing it is caused by the client using SQL Server 2012.
I'm getting an error when I try to run a simple aggregating query.
SELECT MAX(CAST(someDate as datetime)) AS MAX_DT FROM #SomeTable WHERE ISDATE(someDate) = 1
ERROR: Conversion failed when converting date and/or time from character string.
Non-date entries should be removed by WHERE clause, but that doesn't seem to be happening. I can work around with an explicit CASE statement inside the MAX(), but I don't want to hack up the query if I can avoid it. If I use a lower COMPATIBILITY_LEVEL, it works fine. If I have fewer than 2^17 rows, it works fine.
-- SQLServer 15.0.4043.16
USE AdventureWorks;
GO
ALTER DATABASE AdventureWorks SET COMPATIBILITY_LEVEL = 150;
GO
-- delete temp table if exists
DROP TABLE IF EXISTS #SomeTable;
GO
-- create temp table
CREATE TABLE #SomeTable (
someDate varchar(20) DEFAULT GETDATE()
);
-- load data, need at least 2^17 rows with at least 1 bad date value
INSERT #SomeTable DEFAULT VALUES;
DECLARE #i int = 0;
WHILE #i < 17
BEGIN
INSERT INTO #SomeTable (someDate) SELECT someDate FROM #SomeTable
SET #i = #i + 1;
END
GO
-- create invalid date row
WITH cteUpdate AS (SELECT TOP 1 * FROM #SomeTable)
UPDATE cteUpdate SET someDate='NOT_A_DATE'
-- error query
SELECT MAX(CAST(someDate as datetime)) AS MAX_DT
FROM #SomeTable
WHERE ISDATE(someDate) = 1
--ERROR: Conversion failed when converting date and/or time from character string.
-- delete temp table if exists
DROP TABLE IF EXISTS #SomeTable;
GO
I would recommend try_cast() rather than isdate():
SELECT MAX(TRY_CAST(someDate as datetime)) AS MAX_DT
FROM #SomeTable
This is a much more reliable approach: instead of relying on some heuristic to guess whether the value is convertible to a datetime (as isdate() does), try_cast actually attempts to convert, and returns null if that fails - which aggregate function max() happily ignores.
try_cast() (and sister functions try_convert()) is a very handy functions, that many other databases are missing.
I actually just encountered the same issue (except I did cast to float). It seems that the SQL Server 2019 Optimizer sometimes (yes, it's not reliable) decides to execute the calculations in the SELECT part before it applies the WHERE.
If you set compatibility level to a lower version this also results in a different optimizer being used (it always uses the optimizer of the compatibility level). Older query optimizers seem to always execute the WHERE part first.
Seems lowering the compatibility level is already the best solution unless you want to replace all CAST with TRY_CAST (which would also mean you won't spot actual errors as easily, such as a faulty WHERE that causes your calculation to then return NULL instead of the correct value).
I have a situation where I might have a date to search on and I might not. I have a variable that creates a where clause: where field1 = date, if there is a date otherwise i create a blank varable. the problem is adding this to the end of my sql statement.
Select * from table + #where
Select # from table & #where
neither work
msg 102, Level 15, State 1, Line 65
Incorrect syntax near '+'
The best practice would be a procedure with code that allows having a NULL argument. Dynamic SQL can get injected if done poorly or become hard to maintain if you have conditional branches to add more joins, clauses in the WHERE, etc.
CREATE PROCEDURE your_proc
#search_date DATETIME
AS
BEGIN
SELECT *
FROM your_table
WHERE your_date_col >= ISNULL(#search_date, '9999-12-31')
END
GO
Now, if you have a variable, you can call your procedure with it:
DECLARE #variable DATETIME = '2018-01-01'
EXEC your_proc #variable
Or, you can leave it NULL and run the same code:
EXEC your_proc NULL
you can alter the where clause so it will only use the variable when it is not empty,
like this for example
declare #SearchValue date = null -- set a date here if you want to use this variable in the where clause
select t.*
from YourTable t
where (#SearchValue is null or t.YourDateColumn = #SearchValue)
when the variable #SearchValue is empty, then there will be no check done because the expression between the brackets will already be true
Like this you can avoid using dynamic sql
I have the following SQL insert statement inside the loop which iterate through a cursor:
SELECT #q_sql = 'INSERT INTO SYS_PARAMETER(parameter_uno, parameter_key, description, parameter_value, comments, created_date, created_user_id, created_user_name, last_modified_user, last_modified_date, module_uno, data_type)
VALUES ('+#sysparam_uno + ','''+#q_parameter_key+''','''','''+b.pairvalue+''','''',
getdate(),''setup'',''setup'',''setup'',getDate(),'''+#q_module_uno+''','''')'
from UTIL_pairkeys a
INNER JOIN UTIL_pairvalues b on a.pairkeyuno = b.pairkeyuno
and b.languno = 1
where a.pairkey=#q_parameter_key
EXEC sp_executesql #q_sql
Due to value coming to b.pairvalue parameter having a single quote, insert statement fails on SQL Server 2005, but work well on SQL Server 2008R2 and later versions. Any knows reason for this? I know that insert statement fails once parameter value has single quote in between varchar columns. But this something strange here.
Sample insert statement as follows;
INSERT INTO SYS_PARAMETER(parameter_uno,parameter_key,description,parameter_value,comments,created_date,created_user_id,created_user_name,last_modified_user,last_modified_date,module_uno,data_type)
values (269,'application.fs.company','','St John's Foods','',getdate(),'setup','setup','setup',getDate(),'1','')
If it is a problem of single quote only than you can replace it by two single quotes like this:
replace( b.pairvalue ,'''','''''')
I order to escape ', you need to replace it with '':
SELECT #q_sql = '
INSERT INTO SYS_PARAMETER(parameter_uno,parameter_key,description,parameter_value,comments,created_date,created_user_id,created_user_name,last_modified_user,last_modified_date,module_uno,data_type)
values ('+#sysparam_uno + ','''+#q_parameter_key+''','''','''+REPLACE(b.pairvalue, '''', '''''')+''','''',getdate(),''setup'',''setup'',''setup'',getDate(),'''+#q_module_uno+''','''')'
from UTIL_pairkeys a
INNER JOIN UTIL_pairvalues b on a.pairkeyuno = b.pairkeyuno
and b.languno = 1
where a.pairkey=#q_parameter_key
EXEC sp_executesql #q_sql
However, it's best if you could use parametrisation instead:
DECLARE #pair_value VARCHAR(100)
SELECT #pair_value = b.pair_value
from UTIL_pairkeys a
INNER JOIN UTIL_pairvalues b on a.pairkeyuno = b.pairkeyuno
and b.languno = 1
where a.pairkey=#q_parameter_k
SELECT #q_sql = '
INSERT INTO SYS_PARAMETER(parameter_uno,parameter_key,description,parameter_value,comments,created_date,created_user_id,created_user_name,last_modified_user,last_modified_date,module_uno,data_type)
VALUES( #parameter_uno_param,
#parameter_key_param,
'''',
#parameter_value_param,
'''',
getdate(),
''setup'',
''setup'',
getdate(),
''setup'',
#module_uno_param,
'''')'
EXEC sp_executesql
#q_sql,
N' #parameter_uno_param VARCHAR(100),
#parameter_key_param VARCHAR(100),
#parameter_value_param VARCHAR(100),
#module_uno_param VARCHAR(100)
',
#sysparam_uno,
#q_parameter_key,
#pair_value,
#q_module_uno
This assumes your select will only find one pair_value. If more, you need to consider looping through those.
Above code segment call by java program and since SQL Server 2005 thrown an exception to the calling java program it cause to break the java program itself. However, for SQL Server 2008, it look like database engine it self handle the exception without throwing exception to the calling application. To prove that I added try catch block to the error prone code segment and ran the java program against the SQL Server 2005. So, calling application didn't break. Did same against the SQL Server 2008 R2 and result was same.
I am writing a function to process some CSV data. This is what I have written so far...
CREATE FUNCTION dbo.FGetCommaSeperatedValues(#csv as text)
RETURNS #tblIds TABLE(id int,csvlength int)
AS
BEGIN
DECLARE #csvlength AS int
--SET #csvlength = datalength(#csv);
SET #csvlength = 7685
DECLARE #currentIndex AS int
SET #currentIndex = 0
WHILE #currentIndex < #csvlength
BEGIN
--INSERT INTO #tblIds SELECT #currentIndex,#csvlength
INSERT INTO #tblIds (id,csvlength) values (#currentIndex,#csvlength)
SET #currentIndex = #currentIndex+1
END
RETURN
END
My issue is that when I execute the function, using the following command...
SELECT * FROM FGetCommaSeperatedValues('')
The table returned does not show the results that I expect.
Everything is fine until around row 3624 or so (as expected, id column increments by 1)
Then the values increment erratically.
My colleague tested this code in SQL Server 2008 and everything works fine. This appears to be isolated to SQL server 2000.
Does anyone know of this bug, and/or it's resolution?
In order to gaurantee sort order in SQL Server you must use the ORDER BY clause.
ORDER BY CLAUSE