Set count to variable - sql

I would like to assign the number of rows of my table to a variable.
DECLARE #ROW_COUNT nvarchar(1000);
SET #sql_row_count = 'SELECT COUNT(*) FROM ' + #TABLE_NAME;
EXEC sp_executesql #sql_row_count, #ROW_COUNT OUTPUT;
SET #ROW_COUNT = cast(#ROW_COUNT as int);
SELECT #ROW_COUNT;
#ROW_COUNT returns null.
Thank for help.

Comments on your existing query
#ROW_COUNT should be integer. You don't need to use CAST() if you defined it as integer.
You need to assign #ROW_COUNT to COUNT(*).
use QUOTENAME() on the #TABLE_NAME to avoid sql injection.
define the parameters for sp_executesql.
Modified query as follow
DECLARE #ROW_COUNT INT;
DECLARE #sql_row_count NVARCHAR(MAX)
SET #sql_row_count = 'SELECT #ROW_COUNT = COUNT(*) FROM ' + QUOTENAME(#TABLE_NAME);
-- print out for verification
PRINT #sql_row_count
EXEC sp_executesql #sql_row_count, N'#ROW_COUNT INT OUTPUT', #ROW_COUNT OUTPUT;
-- SET #ROW_COUNT = cast(#ROW_COUNT as int);
SELECT #ROW_COUNT;

You need to alter the dynamic query by adding a variable that will
be assigned the value Count(*) and change the call sp_executesql by adding a description of this variable.
Declare #ROW_COUNT Int;
Declare #TABLE_NAME sysname = 'TableName';
Declare #sql_row_count nVarChar(max);
SET #sql_row_count = 'SELECT #ROW_COUNT=COUNT(*) FROM ' +
#TABLE_NAME;
EXEC sp_executesql #sql_row_count, N'#ROW_COUNT Int OUTPUT',
#ROW_COUNT=#ROW_COUNT OUTPUT
SELECT #ROW_COUNT;

Related

SQL Server Default Column value from function

I want to set default value to Id column in Person table with a function
that goes like this:
Function:
IF OBJECT_ID ( 'GetLastId','FN') IS NOT NULL
DROP function GetLastId;
GO
CREATE FUNCTION [dbo].[GetLastId]
(#TableName nvarchar(max))
RETURNS int
AS
BEGIN
DECLARE #LastId int;
DECLARE #sql nvarchar(max);
SET #sql = 'SELECT #LastId = ISNULL(MAX(Id), 0) + 1 FROM ' + #TableName + ';'
EXECUTE sp_executesql #sql, N'#LastId int output', #LastId = #LastId output;
RETURN #LastId
END
and then:
UPDATE Person
SET Id = dbo.GetLastId('Person')
Running this code throws an error:
Only functions and some extended stored procedures can be executed from within a function.
So how to fix this and make it work as a default value?
And please do not say "Use triggers..." as I intend to use it with Entity Framework Core as default value for primary keys.
Thanks
You want a stored procedure, not a function:
create procedure [dbo].[GetLastId] (
#TableName nvarchar(max),
#LastId int output
) as
begin
declare #sql nvarchar(max);
set #sql = 'select #LastId = ISNULL(MAX(Id), 0) + 1 from ' + #TableName + ';'
EXECUTE sp_executesql #sql,
N'#LastId int output',
#LastId=#LastId output;
end;
You should also use quotename() around the table name to prevent unexpected things from happening.
Then you would call this as:
declare #lastId int;
exec dbo.GetLastId('Person', #lastid output);
update Person
set Id = #lastId;
You need to create stored procedure instead of function
create procedure [dbo].[GetLastId] (
#TableName nvarchar(max),
#ColumnName nvarchar(200),
#LastId int output
) as
begin
declare #sql nvarchar(max);
set #sql = 'select #LastId = ISNULL(MAX('+ #ColumnName +'), 0) + 1 from ' + #TableName + ';'
EXECUTE sp_executesql #sql,
N'#LastId int output',
#LastId=#LastId output;
end;
Then you can execute sp like below
declare #lastId int
exec dbo.GetLastId 'Person', 'Id' , #lastid output;
select #lastId
update Person
set Id = #lastId;

How to get value by dynamic field Name using sql select query

I am passing dynamic column name base that column name to get the value and below i my table
Table_CandidateInfo
Id Name Age City
1 Mazhar 30 Gulbarga
20 Khan 29 Bidar
Example1
Declare #ColumnName varchar(100), #Id int
set #ColumnName='Age'
set #Id=20
select * from Table_CandidateInfo where ID=#Id and
I am not able to pass ColumnName with and query because column name is dynamic pass by code. My output should be
29
Example2: If my #ColumnName='City' and #Id=20 then output should be like below
Bidar
I think what you are actually after is the below:
DECLARE #ColumnName sysname, #Id int;
SET #Id = 29;
SET #ColumnName = N'Age';
DECLARE #SQL nvarchar(MAX);
SET #SQL = N'SELECT ' + QUOTENAME(#ColumnName) + N' FROM dbo.Table_CandidateInfo WHERE Id = #Id;';
--PRINT #SQL; --Your debugging friend
EXEC sp_executesql #SQL, N'#Id int', #Id = #Id;
Alas, you cannot pass identifiers as parameters. You need to use dynamic SQL:
declare #columnName varchar(100);
declare #Id int;
set #ColumnName = 'Age' ;
set #Id = 20;
declare #sql nvarchar(max);
set #sql = '
select *
from Table_CandidateInfo
where [columnName] = #Id';
select #sql = replace(#sql, '[columnName]', quotename(#columnName));
exec sp_executesql #sql,
N'#id int',
#id=#id;

Dynamic SQL output of a query to a variable

I would like to output the result of the dynamic SQL into a variable called #Count but not sure what the syntax or even the code should like to accomplish this.
The code looks as follows:
declare #tab nvarchar(255) = 'Person.person'
declare #Count int
declare #SQL nvarchar(max) = 'select count(*) from '+ #tab
exec(#SQl)
select #Count
thank you
Here's another way to do it that also safely addresses the SQL Injection isuues:
/* Counts the number of rows from any non-system Table, *SAFELY* */
-- The table name passed
DECLARE #PassedTableName as NVarchar(255) = 'Person.Person';
-- Make sure this isn't a SQL Injection attempt
DECLARE #ActualTableName AS NVarchar(255)
SELECT #ActualTableName = TABLE_SCHEMA + '.' + TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = PARSENAME(#PassedTableName,1)
AND TABLE_SCHEMA = PARSENAME(#PassedTableName,2)
-- make a temp table to hold the results
CREATE TABLE #tmp( cnt INT );
-- create the dynamic SQL
DECLARE #sql AS NVARCHAR(MAX)
SELECT #sql = 'SELECT COUNT(*) FROM ' + #ActualTableName + ';'
-- execute it and store the output into the temp table
INSERT INTO #tmp( cnt )
EXEC(#SQL);
-- Now, finally, we can get it into a local variable
DECLARE #result AS INT;
SELECT #result = cnt FROM #tmp;
You can utilize sp_executesql to execute your count() query, and output it #Count.
Try this:
-- Set the table to count from
declare #tab nvarchar(255) = 'Person.person'
-- Assign the SQL query
declare #SQL nvarchar(255) = N'SELECT count(*) FROM ' + #tab
-- Pepare for sp_executesql
declare #Count int
declare #Params nvarchar(100) = N'#Count int output'
-- Set the count to #Count
exec sp_executesql #SQL, #Params, #Count=#Count output
-- Output #Count
select #Count
One last thing: Person.person looks like you might be trying to reference a person column from a Person table. But the above query is a literal representation of what it looks like you're trying to achieve in your question.
The below question is pretty much identical to what you are asking here.
sp_executeSql with output parameter
DECLARE #retval int
DECLARE #sSQL nvarchar(500);
DECLARE #ParmDefinition nvarchar(500);
DECLARE #tablename nvarchar(50)
SELECT #tablename = N'products'
SELECT #sSQL = N'SELECT #retvalOUT = MAX(ID) FROM ' + #tablename;
SET #ParmDefinition = N'#retvalOUT int OUTPUT';
EXEC sp_executesql #sSQL, #ParmDefinition, #retvalOUT=#retval OUTPUT;
SELECT #retval;

Selecting a value into a variable

I'm playing around with t-sql and would like to be able to select into some variable.
Currently I just want to get a count(*) for every table in the database and print this.
When I try the following:
EXEC('SELECT COUNT(*) FROM '+ #table_name)
This gives the counts for all rows, now, I'd like to store the COUNT(*) into a variable. To achieve this i've declared. I've tried a few different approaches, amongst others this one:
EXEC('SELECT ' + #row_count +' = COUNT(*) FROM '+ #table_name)
Which yields an error (Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '='.).
Any idea how to correctly express this?
You'll have to use sp_executesql.
Check this article for more info.
There is a more efficient way to get the number of rows in a table, by looking at the database metadata. Here is an alternative solution:
declare #NumRows int;
select #NumRows = sum(rows)
from <database>.sys.partitions P join
<database>.sys.tables T
on T.[object_id] = P.[object_id]
where index_id IN (0,1) AND T.[type] = 'U' and t.name = '<table>'
You need to provide output variable from a query and specify that it is for output:
declare #table_name nvarchar(100)
declare #row_count int
declare #sql nvarchar(max)
set #table_name = 'YOUR TABLE NAME'
set #sql = N'SELECT #row_count = COUNT(*) FROM '+ #table_name
exec sp_executesql #sql, N'#row_count int output', #row_count = #row_count output
print #row_count
Variable has to be declared in the appropriate context. try
declare #table_name varchar(50)
set #table_name ='users'
EXEC('declare #rcnt int;SELECT #rcnt = COUNT(*) FROM '+ #table_name+';select #rcnt ')
Probably do like this:
declare #rowcount int
declare #table_name nvarchar(10)
declare #sql nvarchar(max);
set #table_name = N'test';
set #sql = N'SELECT COUNT(*) FROM '+#table_name;
execute sp_executesql #sql,N'#rowcount int output',#rowcount = #rowcount output;
select #rowcount;

Dynamic sql statement to update a variable

my sql statement is something like this below
DECLARE #OLD_NAV_VALUE AS INT
DECLARE #FINAL AS INT
SELECT #OLD_NAV_VALUE = [col1] from TBL_BA where DATE = #id_Date
SET #FINAL = #OLD_NAV_VALUE * 50
But the problem i am haveing here is that the column name in the select statement which is given as [col1] is a dynamic value. So i am trying something like this below.
DECLARE #OLD_NAV_VALUE AS INT
DECLARE #FINAL AS INT
EXEC('SELECT #OLD_NAV_VALUE = [' + #DYNAMIC_COL_NAME + '] from TBL_BA where DATE = ' + #id_Date)
SET #FINAL = #OLD_NAV_VALUE * 50
this gives an error that #OLD_NAV_VALUE has to be declared. So i tried declaring #OLD_NAV_VALUE inside the EXEC statement. But if i do this i am not able to use the same outside the EXEC statement.
Please let me know how to do this.
You can also use the sp_executesql statement with an output parameter:
declare #field nvarchar(50);
set #field = N'FieldToSelect';
declare #sql nvarchar(3000);
declare #parmDefinition nvarchar(500);
SET #parmDefinition = N'#returnValueOUT nvarchar(50) OUTPUT';
set #sql = N'SELECT #ReturnValueOUT = ' + #Field + ' FROM [TableName] WHERE [SomeCondition]'
declare #returnValue nvarchar(50);
EXECUTE sp_executesql #sql, #parmDefinition, #returnValueOut = #returnValue OUTPUT;
SELECT #returnValue
First, I'd suggest that you do a Google on "Erland dynamic SQL" and read his white paper on the subject.
Your design is probably not the best if it requires that you use a dynamic column name like this.
The reason that you can't do what you're trying to do is that everything in the EXEC is entirely in its own scope. If you absolutely have to do it this way though then you could use a table (either a normal table, or a global temporary table) to store the value for use outside of the EXEC.
We've used sp_executesql. Here's another example of a parameterized record count:
DECLARE #sql AS nvarchar(MAX)
SET #sql = N'SELECT #RecordCount = COUNT(*) FROM [{#SchemaName}].[{#TableName}]'
SET #sql = REPLACE(#sql, '{#SchemaName}', #SchemaName)
SET #sql = REPLACE(#sql, '{#TableName}', #TableName)
DECLARE #RecordCount AS int
EXEC sp_executesql
#query = #sql,
#params = N'#RecordCount INT OUTPUT',
#RecordCount = #RecordCount OUTPUT
This worked for me.
I declared a temp table and used it to receive the values from the select statement.
Something like below.
declare #i int
declare #v int
create table #t (val int)
insert into #t
exec ('declare #i int set #i = 0 select #i+1')
select * from #t