I am trying to compare data from a table in SQL Server with a variable value, and I get the error
Must declare the scalar variable #DataSearched
This is my query:
DECLARE #DateSeached INT
SET #DateSeached = '9'
SELECT *
FROM Tax2ComputationType as t
INNER JOIN ComputationValue as c ON t.TaxId != c.ComputationTaxId
WHERE t.ValidityStartDate BETWEEN c.ValidityStartDate AND c.ValidityEndDate
AND t.ValidityEndDate > #DateSeached
I have also tried writing the code like this:
DECLARE #sql nvarchar(max)
SET #sql = 'SELECT * .....' and so on
SET #sql = #sql + 'AND t.ValidityEndDate >' + #DateSearched
And I get the same error. I searched for a time the answer and I couldn't find it. Can anyone help me?
Related
I have a SELECT statement that can produce a list of values:
DECLARE #ValueList varchar(Max);
SELECT #ValueList = COALESCE(#ValueList + ',', '') + CAST(Val AS varchar(max))
FROM
(SELECT TOP (100) PERCENT tblSampleTable.SomeIDNumber AS Val
FROM tblSampleTable) AS ValuesThisYear
PRINT #ValList
This returns a list with values something like
val1,val2,val4,val9,
etc., ehich I can then feed into a stored procedure, or manage some other way.
Now I want to have the query that gets assessed for the list of values to be dynamic, maybe passed in or from another stored procedure, similar to this:
DECLARE #ValueList varchar(Max);
DECLARE #TSQL varchar(Max);
SET #TSQL = {stored proc to get base query}
SELECT #ValueList = COALESCE(#ValueList + ',', '') + CAST(Val AS varchar(max))
FROM
(#TSQL) AS ValuesThisYear
PRINT #ValList
I know that's the wrong syntax for including #TSQL, and that's what I'm trying to find out. I've viewed a number of threads and tried a number of methods, but am still not able to incorporate this dynamic part.
The tricky part seems to be the making of the list (the COALESCE and CAST statements), where I incorporate #ValList as part of the returned string.
Any help would be appreciated!
Dynamic SQL is usually about
Creating a variable that contains the exact SQL you want to run
Then using EXEC (#SQLvariable) to run that code
For example (not for production yet!) I've added a new variable #CustomSQL
DECLARE #ValueList varchar(Max);
DECLARE #TSQL varchar(Max);
DECLARE #CustomSQL varchar(Max);
SET #TSQL = {stored proc to get base query}
SET #CustomSQL =
'SELECT COALESCE(#ValueList + '','', '''') + CAST(Val AS varchar(max))
FROM (
' + #TSQL + '
) As ValuesThisYear;'
PRINT #CustomSQL
EXEC (#CustomSQL)
Notice that adding text/strings (e.g., the #TSQL variable) have to be entered as exact strings rather than their variable names. Also note apostrophes - you need to use '' every time you wish to refer to a '.
I also removed the variable name from the SELECT #ValueList = ... because the dynamic SQL cannot actually reference the variables - it has its own scope (?cannot remember the correct word) and doesn't have access to the variables. Solutions to this include
Using a temporary table e.g., #temp which can be referenced
Using the OUTPUT clause
Personally, I would approach it a different way - use the T-Sql provided to put data into a temporary table. Then use the temporary table in the other statement e.g.,
DECLARE #ValueList varchar(Max);
DECLARE #TSQL varchar(Max);
SET #TSQL = {stored proc to get base query}
DECLARE #CustomSQL varchar(Max)
CREATE TABLE #temp (Val varchar(1000))
SET #CustomSQL = 'INSERT INTO #temp (Val) ' + #TSQL
EXEC (#CustomSQL)
SELECT #ValueList = COALESCE(#ValueList + ',', '') + CAST(Val AS varchar(max))
FROM #temp As ValuesThisYear;
PRINT #ValList
I almost never get my dynamic SQL correct first try. Suggestions
Keep it as simple as possible
Before having a version that runs (e.g., EXEC (#CustomSQL)), comment the EXEC out and PRINT it instead.
Here are some examples from previous posts I've done recently
Query for R Machine Learning Services - Filtering Categories in Where Clause
Bottom of Dynamic columns depend on previous dynamic columns - TSQL
I am trying to find an alternative to setting the content of a variable as a big query in which i'm dynamically replacing values.
Is it possible to do something like this?
declare #serv nvarchar(max)
set #serv = '[linkedServName].[dataBaseName]'
select top 10 * from #serv.dbo.someTable
If yes, could you please show me the correct syntax?
Thank you for your time
If you want to parameterize the server and database you select from, then you have to use dynamic sql. Try this:
declare #serv nvarchar(max)
declare #qry nvarchar(max)
set #serv = '[linkedServName].[dataBaseName]'
set #qry = 'select top 10 * from ' + #serv + '.dbo.someTable'
exec(#qry)
I'm currently having trouble writing a stored procedure and setting the value of a variable of type int to the results of a select statement with a variable as the tablename. I've looked at old threads and tried multiple methods, but no luck. If I'm not getting an error regarding the tablename, I end up getting an error with a variable conversion issue. I've been working on this for too long and any help would be appreciated. Below is a portion of my code. Thanks
DECLARE #BATCHNUMBER VARCHAR --value set in earlier code
DECLARE #ETABLE VARCHAR(50); --the table name
DECLARE #FIRSTDOCID INT;
SET #ETABLE = 'tablename_' + #BATCHNUMBER; --CREATE FIRST TABLE NAME
SELECT #FIRSTDOCID = MIN(D0CID) FROM #ETABLE
The error I get is: Must declare the table variable "#ETABLE"
You are trying to select from a VARCHAR, not a table. The only way to make this work is by using Dynamic SQL.
DECLARE #SQL NVARCHAR(250);
SET #SQL = 'SELECT #OUTPUT = MIN(D0CID) FROM ' + QuoteName(#ETABLE);
EXEC sp_executeSql #SQL, N'#output INT OUTPUT', #FIRSTDOCID OUTPUT;
SELECT #FIRSTDOCID;
However, I would not suggest using Dynamic SQL as this often leads to SQL injection.
You'll probably have to do something like use exec if you're dynamically building the query:
SET #QUERY = "SELECT" + ...etc.
exec(#QUERY)
Since ETABLE is a varchar, and not, as expected, a 'table variable'.
I have written this stored procedure :
CREATE PROCEDURE [dbo].[spGetCuisines]
#RestaurantID INT ,
#CuisineID NVARCHAR(200)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX)
SET #sql = 'SELECT CuisineID, CuisineName
FROM dbo.Cuisine1
WHERE CuisineID IN (
SELECT dbo.Dishes1.CuisineID
FROM dbo.Dishes1
WHERE DishID IN ( SELECT DishID
FROM dbo.RestaurantDish
WHERE RestaurantID = '
+ CAST(#RestaurantID AS NVARCHAR(MAX)) + ' ) )'
IF #CuisineID <> ''
BEGIN
SET #sql += 'AND Cuisine1.CuisineID IN('
+ CAST(#CuisineID AS NVARCHAR(MAX)) +')'
END
EXECUTE sp_executesql #sql;
END
I am using 3 tables with their columns listed below:
Dishes1
DishID
DishName
CuisineID
Price
Cuisine1
CuisineID
CuisineName
Type
DateCreated
DateModified
DateDeleted
RestaurantDish
RestaurantDishID
RestaurantID
DishID
but my stored procedure gives me syntax error on this line:
SET #sql += 'AND Cuisine1.CuisineID IN('+ CAST(#CuisineID AS NVARCHAR(MAX)) +')'
it says:
incorrect syntax near "+"
Can somebody guide me? Does the SQL Server version have something to do with this?
The syntax you are using is only valid on SQL Server 2008 and above. On SQL Server 2005, you'll have to change:
SET #sql += ...
To:
SET #sql = #sql + ...
There's absolutely no need to use dynamic SQL here - so don't ! Also: prefer JOIN over subqueries - joins are typically faster, and quite frankly - code is much easier to read!
Just use:
CREATE PROCEDURE [dbo].[spGetCuisines]
#RestaurantID INT ,
#CuisineID NVARCHAR(200)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX)
SELECT
c.CuisineID, c.CuisineName
FROM
dbo.Cuisine1 c
INNER JOIN
dbo.Dishes1 d ON d.CuisineID = c.CuisineID
INNER JOIN
dbo.Restaurant1 r ON r.DishID = d.DishID
WHERE
r.RestaurantID = #RestaurantID
AND (#CuisineID = '' OR c.CuisineID = #CuisineID)
END
And Aaron Bertrand is absolutely right, of course - this only works if you pass in a single CuisineID as string.
If your #CuisineID parameter contains multiple values then you need something like this instead:
WHERE
r.RestaurantID = #RestaurantID
AND (#CuisineID = '' OR c.CuisineID IN dbo.Split(#CuisineID))
Using a function Split you can split up a comma-separated list of ID's into a table variable and use the IN operator to match to a list of possible values.
are you perhaps passing in a comma delimited string??
If so, there is a better way to handle this, see here:
http://codebetter.com/raymondlewallen/2005/10/26/quick-t-sql-to-parse-a-delimited-string/
I'm doing a basic query where I'm doing
Select Lower(column-name) from table
Now if I want to do a lower case on more than one column, I would need to do a
Select Lower(col1), Lower(col2) from table
I wanted to know if it's possible to do lowercase function application on all columns.
Something like
Select Lower(*) from table
This is not a valid statement, when I'm trying on sqlite3 and I'm guessing it's same for other vendors too. Has anybody been able to do this via a different approach. PL/SQL or T-SQL maybe.
No. It isnt possible to fetch all columns in lower case all at once.
I concur that there is no way to do this without mentioning each column. But since your consuming application will presumably have to loop through all columns and rows anyway, I suggest that is the right place to transform this data anyway...
While its not possible to use an inbuilt sql construct to achieve this, yet a small sql script should solve the purpose. Please consider the script given below:
declare #number_of_columns int
declare #counter int
declare #query nvarchar(max)
declare #column_name nvarchar(max)
set #query = 'select '
set #counter = 1
select #number_of_columns = count(ordinal_position) from information_schema.columns where table_name = '<your table name>'
while(#counter <= #number_of_columns)
begin
select #column_name = column_name from information_schema.columns
where table_name = '<your table name>' and ordinal_position = #counter
if(#counter < #number_of_columns)
begin
Set #query = #query + 'lower(' + (#column_name) + '),'
end
else
begin
Set #query = #query + 'lower(' + (#column_name) + ')'
end
set #counter = #counter + 1
end
set #query = #query + ' from <your table name>'
select #query
EXEC sp_executesql #query = #query
While, the above script would not work for 'ntext' data type implicitly as its explicit conversion to varchar is required to apply 'lower' function, also the script might not be required for data types like 'int','datetime' etc. So modify the script by applying additional conditions on the data types of the columns.