Stored procedure to find number of rows in a table - sql

In a stored procedure I pass a table name as the input variable.
I want to return the number of rows of this table with that stored procedure.
I tried something like this but it did not work:
declare #maxRowCount bigint
exec('set '+ #maxRowCount + ' =(select COUNT(1) from ' + #tableName + ')')
This is SQL Server 2008.

You can try this
CREATE PROCEDURE dbo.sp_selectcount
#tablename NVARCHAR(200)
AS
DECLARE #cmd NVARCHAR (255)
SET #cmd = 'SELECT count(*) from ' + #tablename
EXEC sp_executesql #cmd

The following example should give you something to work with.
-- fully qualify your table name (this is probably an input value in your sproc?)
-- please note that I use system view master.sys.tables as an example table here
DECLARE #tablename NVARCHAR(MAX) = N'[master].[sys].[tables]';
-- build the sql statement that you will execute
DECLARE #sql NVARCHAR(MAX) = N'SELECT COUNT(*) FROM ' + #tablename;
-- create a variable to hold the number of rows later on
DECLARE #nrofrows BIGINT;
-- create a temp table to store the result of executing the sql statement
CREATE TABLE #temp (NrOfRows BIGINT);
-- insert the result of the execution of the sql statement into the temp table
INSERT INTO #temp
EXECUTE(#sql);
-- extract the number of rows from the temp table
SET #nrofrows = (SELECT NrOfRows FROM #temp);
-- check the result so you can test!
PRINT #nrofrows;
If you want good background information on dynamic SQL, check out Erland Sommarskogs article The Curse and Blessings of Dynamic SQL.

You should remove the quotes around #maxRowCount.
Try this:
declare #maxRowCount bigint
exec('set #maxRowCount =(select COUNT(*) from ' + #tableName + ')')
OR
exec('SELECT #maxRowCount = COUNT(*) from ' + #tableName)
Analysis:
With the query you tried, it will execute:
set blablabla = (select count(1) from MyTable)
By removing the quotes:
set #maxRowCount = (select count(*) from MyTable)

You can try this instead.
declare #maxRowCount bigint(5)
exec('SELECT COUNT(*) INTO #maxRowCount FROM ' + #tableName)

Related

How to retrieve a column name from a table that is stored as a value in another table

I'm pretty new to sql so any help will be much appreciated
I have a table containing a list of table names in a column of a table and I need to retrieve a column called [Last Refreshed] from all the tables listed. The tables all have different structures but they all have the [Last Refreshed] Column. I have managed to insert the tablenames into a sql variable but up to this point I am kind of stuck.
I hope I managed to explain what I need but I have attached my code as well.
Declare #tables nvarchar(max)
Declare #sql nvarchar(max)
Declare #cnt int
DECLARE #Counter int
SET #Counter = 1
DECLARE #RowCount INT
SET #RowCount = (SELECT COUNT(*)
FROM (
SELECT * FROM TABLE_LIST1
UNION
SELECT * FROM TABLE_LIST2) data )
DROP TABLE #DB_DUMMY
CREATE TABLE #DB_DUMMY (
[TABLENAME] VARCHAR(512),
[LAST_REFRESHED] VARCHAR(533)
);
WHILE ( #Counter <= #RowCount)
BEGIN
SELECT #tables = FinalTable, #cnt = Row_num from (
SELECT FinalTable , ROW_NUMBER() OVER(ORDER BY FinalTable DESC) AS Row_num
FROM (
SELECT FinalTable FROM TABLE_LIST1
UNION
SELECT FinalTable FROM ABLE_LIST2) data
group by FinalTable) a
where Row_num = #Counter
--This part doesnt work
INSERT INTO #DB_DUMMY(TABLENAME,LAST_REFRESHED)
SELECT #tables , [Last Refreshed] from #tables
SET #Counter = #Counter + 1
END
exec(#sql)
I expect to see a list of tablenames as well as the last refresh in the temporary table #DB_DUMMY
i add the [Last Refreshed] column to my tables and write this query and give me the correct answer
DROP TABLE IF EXISTS #DB_DUMMY
CREATE TABLE #DB_DUMMY (
[TABLENAME] VARCHAR(512),
[LAST_REFRESHED] VARCHAR(533)
);
DECLARE #COMMAND NVARCHAR(MAX)
SELECT #COMMAND = STRING_AGG(' INSERT INTO #DB_DUMMY SELECT DISTINCT '+CHAR(39)+T.name+CHAR(39)+',['+C.name+'] FROM '+S.name+'.'+T.name + ' GO', CHAR(13)+CHAR(10))
FROM sys.all_columns C
INNER JOIN sys.tables T ON C.object_id = T.object_id
INNER JOIN sys.schemas S ON T.schema_id = S.schema_id
WHERE C.name = 'Last Refreshed'
PRINT(#COMMAND)
EXEC(#COMMAND)
SELECT * FROM #DB_DUMMY
two first line with IF EXISTS is new syntax in sql server 2017
Just a suggestion You could use a INSERT SELECT
INSERT INTO #DB_DUMMY(TABLENAME,LAST_REFRESHED)
SELECT 'TABLE_LIST1', LAST_REFRESHED
FROM TABLE_LIST1
UNION ALL
SELECT 'TABLE_LIST2', LAST_REFRESHED
FROM TABLE_LIST2
UNION ALL
.....
SELECT 'TABLE_LISTN', LAST_REFRESHED
FROM TABLE_LISTN
Try something like this:
declare cur cursor for Select TableName From TABLE_LIST
declare #tablename nvarchar(max)
declare #sqlstring nvarchar(max)
open cur
fetch next from cur into #tablename
while ##fetch_status=0
begin
set #sqlstring = 'SELECT ''' + #tablename + ''' AS ''TABLE'', [LAST_REFRESHED] FROM ' + #tablename
exec sp_executesql #sqlstring
fetch next from cur into #tablename
end
close cur
deallocate cur
;
It is the weekend and I don't have access to a database to test on, so it may need some adjusting. Here is a fiddle with the sample code, but it only returns the first table http://sqlfiddle.com/#!18/a5b55b/2 (I think the fiddle execution mechanism interferes with the cursor.)
This answer is based upon the code here: I have the same column in multiple tables, and want to update that column in all tables to a specific value. How can I do this?
Note that there is no need to maintain a list of tables with the column. You can generate it dynamically from INFORMATION_SCHEMA.COLUMNS
Another possible approach is to generate and execute a dynamic statement (it's not possible to use a variable for the name of a column or a table):
Table:
CREATE TABLE #TableNames (
[TableName] nvarchar(128)
)
INSERT INTO #TableNames
([TableName])
VALUES
(N'Table1'),
(N'Table2'),
(N'Table3'),
(N'Table4'),
(N'Table5')
Statement:
-- Generate statement
DECLARE #stm nvarchar(max) = N''
SELECT #stm = CONCAT(
#stm,
N'INSERT INTO #DB_DUMMY (TABLENAME, LAST_REFRESHED) ',
N'SELECT ''',
[TableName],
N''' AS [TableName], [LastRefreshed] FROM ',
QUOTENAME([TableName]),
N'; '
)
FROM #TableNames
-- Execute statement
PRINT #stm
EXEC sp_executesql #stm

not able to use sp_executesql command

I need to execute below query
SELECT *, IDENTITY( int ) AS IDColumn INTO #SmootheningTable FROM #TableName
where #SmootheningTable is temporary table
and #TableName is name of table
I need to use command either EXEC or sp_executesql to execute.
If I use EXEC, I wont be able to use #SmootheningTable in later portion of my stored procedure.
And while trying sp_executesql, I am getting error stating #statement error.
How can I use sp_executesql for above given query.
Or is there any other way to execute?
this is the query I am using
DECLARE #TablePlaceHolder VARCHAR(50)='';
DECLARE #SmootheningQuery NVARCHAR(max) = 'SELECT *, IDENTITY( int ) AS IDColumn INTO #SmootheningTable FROM #TablePlaceHolder';
EXEC sp_executesql #SmootheningQuery, N'#TablePlaceHolder varchar(50)', #PlanDetailTempTableName
and i am getting below error
Must declare the table variable "#TablePlaceHolder".
Thanks in advance
There are two issues in your code:-
First : Putting the variable name inside the string, put in out like next:-
instead of this line:-
DECLARE #SmootheningQuery NVARCHAR(max) = 'SELECT *, IDENTITY( int ) AS
IDColumn INTO #SmootheningTable FROM #TablePlaceHolder';
Type this line:-
DECLARE #SmootheningQuery NVARCHAR(max) = 'SELECT *, IDENTITY( int ) AS
IDColumn INTO #SmootheningTable FROM ' + #TablePlaceHolder;
Second: Don't use local temp table within sp_executeSql,
The Local temporary table [with one hash # ] is visible in current session only, use global temporary tables instead [with two hashes ## ] are visible in all sessions,
So instead of
#SmootheningTable
Type
##SmootheningTable
Demo (All Code): -
Create table MyTable (id int , name nvarchar(100))
go
insert into MyTable values (1, 'Ahmed');
insert into MyTable values (2, 'Abdelqader');
go
declare
#TableName varchar(50),
#MyQuery nvarchar(200)
set #TableName = 'MyTable'
set #MyQuery = 'select * Into ##MYTempTable From ' + #TableName
exec sp_executesql #MyQuery
select * from ##MYTempTable
Result:-
id name
1 Ahmed
2 Abdelqader
Please Try This,
CREATE PROC usp_SmootheningTable
AS
BEGIN
SELECT *, IDENTITY( int ) AS IDColumn INTO #SmootheningTable FROM
TableName
SELECT * FROM #SmootheningTable
END
GO
Please try this out
CREATE TABLE #Temp
(
Columns
)
DECLARE #SQL NVARCHAR(MAX)
DECLARE #TableName VARCHAR(MAX)
SET #TableName = 'TableName'
SET #SQL = 'SELECT TOP 10 * FROM '+#TableName
INSERT INTO #Temp
EXEC SP_EXECUTESQL #SQL
SELECT * FROM #Temp

Looping through a column in SQL table that contains names of other tables

I have fairly new to using SQL, currently I have a table that has a column that contains the names of all the tables I want to use for one query, so what I want to do is to loop through that column and go to every single one of these tables and then search one of their columns for a value (there could be multiple values), so whenever a table contains the value, I will list the name of the table. Could someone give me a hint of how this is done? Is cursor needed for this?
I don't have enough reputation to comment but is the table with the column that contain the table names all in one column, meaning that all the table names are comma separated or marked with some sort of separator? This would cause the query to be a little more complicated as you would have to take care of that before you start looping through your table.
However, this would require a cursor, as well as some dynamic sql.
I will give a basic example of how you can go about this.
declare #value varchar(50)
declare #tableName varchar(50)
declare #sqlstring nvarchar(100)
set #value = 'whateveryouwant'
declare #getTableName = cursor for
select tableName from TablewithTableNames
OPEN #getTableName
fetch NEXT
from #getTableName into #tableName
while ##FETCH_STATUS = 0
BEGIN
set #sqlstring = 'Select Count(*) from ' + #tableName + 'where ColumnNameYouwant = ' + #value
exec #sqlstring
If ##ROWcount > 0
insert into #temptable values (#tableName)
fetch next
from #getTableName into #tableName
END
select * from #temptable
drop table #temptable
close #getTableName
deallocate #getTableName
I'm currently not able to test this out as for time constraint reasons, but this is how I would go about doing this.
You could try something like this:
--Generate dynamic SQL
DECLARE #TablesToSearch TABLE (
TableName VARCHAR(50));
INSERT INTO #TablesToSearch VALUES ('invoiceTbl');
DECLARE #SQL TABLE (
RowNum INT,
SQLText VARCHAR(500));
INSERT INTO
#SQL
SELECT
ROW_NUMBER() OVER (ORDER BY ts.TableName) AS RowNum,
'SELECT * FROM ' + ts.TableName + ' WHERE ' + c.name + ' = 1;'
FROM
#TablesToSearch ts
INNER JOIN sys.tables t ON t.name = ts.TableName
INNER JOIN sys.columns c ON c.object_id = t.object_id;
--Now run the queries
DECLARE #Count INT;
SELECT #Count = COUNT(*) FROM #SQL;
WHILE #Count > 0
BEGIN
DECLARE #RowNum INT;
DECLARE #SQLText VARCHAR(500);
SELECT TOP 1 #RowNum = RowNum, #SQLText = SQLText FROM #SQL;
EXEC (#SQLText);
DELETE FROM #SQL WHERE RowNum = #RowNum;
SELECT #Count = COUNT(*) FROM #SQL;
END;
You would need to change the "1" I am using as an example to the value you are looking for and probably add a CONVERT/ CAST to make sure the column is the right data type?
You actually said that you wanted the name of the table, so you would need to change the SQL to:
'SELECT ''' + ts.TableName + ''' FROM ' + ts.TableName + ' WHERE ' + c.name + ' = 1;'
Another thought, it would probably be best to insert the results from this into a temporary table so you can dump out the results in one go at the end?

How to store a dynamic SQL result in a variable in T-SQL?

I have a stored procedure which takes 'table name' as parameter. I want to store my 'exec' results to a variable and display using that variable.
Here is my T-SQL stored procedure..
create procedure DisplayTable( #tab varchar(30))
as
begin
Declare #Query VARCHAR(30)
set #Query='select * from ' +#tab
EXEC (#Query)
END
I want to do something like this..
SET #QueryResult = EXEC (#Query)
select #QueryResult
How do i achieve this.. Please help.. I am a beginner..
You can use XML for that. Just add e.g. "FOR XML AUTO" at the end of your SELECT. It's not tabular format, but at least it fulfills your requirement, and allows you to query and even update the result. XML support in SQL Server is very strong, just make yourself acquainted with the topic. You can start here: http://technet.microsoft.com/en-us/library/ms178107.aspx
alter procedure DisplayTable(
#tab varchar(30)
,#query varchar(max) output
)
as
BEGIN
Declare #execution varchar(max) = 'select * from ' +#tab
declare #tempStructure as table (
pk_id int identity
,ColumnName varchar(max)
,ColumnDataType varchar(max)
)
insert into
#tempStructure
select
COLUMN_NAME
,DATA_TYPE
from
INFORMATION_SCHEMA.columns
where TABLE_NAME= #tab
EXEC(#execution)
declare #ColumnCount int = (SELECT count(*) from #tempStructure)
declare #counter int = 1
while #counter <= #ColumnCount
BEGIN
IF #counter = 1
BEGIN
set #query = (SELECT ColumnName + ' ' + ColumnDataType FROM #tempStructure where pk_id= #counter)
END
IF #counter <> 1
BEGIN
set #query = #query + (SELECT ',' + ColumnName + ' ' + ColumnDataType FROM #tempStructure where #counter = pk_id)
END
set #counter = #counter + 1
END
END
When you execute the SP, you'll now get a return of the structure of the table you want.
This should hopefully get you moving.
If you want the table CONTENTS included, create yourself a loop for the entries, and append them to the #query parameter.
Remember to delimit the #query, else when you read it later on, you will not be able to restructure your table.
First of all you have to understand that you can't just store the value of a SELECTon a table in simple variable. It has to be TABLE variable which can store the value of a SELECTquery.
Try the below:
select 'name1' name, 12 age
into MyTable
union select 'name2', 15 union
select 'name3', 19
--declaring the table variable and selecting out of it..
declare #QueryResult table(name varchar(30), age int)
insert #QueryResult exec DisplayTable 'MyTable'
select * from #QueryResult
Hope this helps!

How to specify a table dynamically in a Stored Procedure

Thanks for the feedback, but I was hoping for help with an UPDATE command, not SELECT.
Can anyone help with the syntax for an UPDATE command?
I am passing a table name into a Stored Procedure but the SQL does not seem to recognize it.
DECLARE #userTable AS VARCHAR(200);
SET #userTable = #currTable
UPDATE #userTable
SET [lang_String] = #lang_String, [date_Changed] = #submitDate1
WHERE (ID = #ID)
#currTable is passed into the Stored Procedure. All tables names are built by design in code.
You can't, you need to build the entire SQL string and then execute it, like this for example:
DECLARE #sql nvarchar(4000)
SELECT #sql = ' SELECT col1, col2, col3 ' +
' FROM dbo.' + quotename(#tblname) +
' WHERE keycol = #key'
EXEC sp_executesql #sql, N'#key varchar(10)', #key
Got this to work quite easily....
#myTable varchar(150)
/* Comments:
*/
AS
SET NOCOUNT ON;
DECLARE #sql varchar(max);
SET #sql = 'SELECT [ID], [StringID], [GUID] FROM ' + #myTable + ' ORDER BY [GUID]';
print (#sql)
EXECUTE(#sql);
SET #langTable = Null;
FYI, the values available for myTable are stored in another table and are not available to users for edit. Table names are built dynamically in code based on a unique combination of values.