dynamic column name in sql server 2008 in stored procedure - sql

Can I use the following syntax in stored procedure,
set #count = (select count(*) from [dbo].[employee] where #column_name ='T')

CREATE PROCEDURE Proc_Name
#Column_Name NVARCHAR(128),
#COUNT INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Sql NVARCHAR(MAX);
SET #Sql = N'SELECT #count = count(*) from [dbo].[employee] where ' + QUOTENAME(#Column_Name)
+ N' =''T'''
EXECUTE sp_executesql #Sql
,N'#COUNT INT OUTPUT'
,#COUNT OUTPUT
END

Related

Dynamically Creating a table and inserting Rows inside a SP

I am trying to run a Stored Procedure that Inserts into a Table.
I keep getting the Incorrect syntax near 'tbl_1_2'.
It doesn't Insert the data.I am using MSSQL2012
Alter PROCEDURE [dbo].[TT] AS
BEGIN
declare #tbl varchar(100);
set #tbl='tbl_1_2';
declare #sql varchar(100);
DECLARE #ptablename VARCHAR(max) = (#tbl)
set #ptablename=#tbl
SET #sql = 'INSERT INTO ' + #ptablename ;
EXEC (#sql)
select *
from (
values('1','2')
) t1 (c1, c2)
End
See this sample and compare with your code to understand your error.
Create Table Test (ID int, Name sysname)
Go
Declare #TableName sysname = 'Test'
DECLARE #ID int = 1
DECLARE #Name sysname = 'Meysam'
Declare #SQL nVarchar(4000) = 'INSERT #TableName (ID, Name) Values (#ID, N''#Name'')'
Set #SQL = REPLACE(#SQL, '#TableName', #TableName)
Set #SQL = REPLACE(#SQL, '#ID', #ID)
Set #SQL = REPLACE(#SQL, '#Name', #Name)
EXEC (#SQL)
SELECT * FROM Test

Is there a way for me to dynamically write a script to add a domain+user to Microsoft SQL server in a stored procedure?

I have to use this exact script below:
ALTER PROCEDURE [dbo].[sp_CheckIfSQLLoginExistsAndCreateLogin]
#SearchDomain NVARCHAR(MAX),
#SearchUsername NVARCHAR(MAX)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(max);
DECLARE #params NVARCHAR(MAX);
IF #SearchUsername != ''
BEGIN
SET #sql = N'IF NOT EXISTS (SELECT * FROM sys.server_principals WHERE [name] = #Domain\#Username) CREATE LOGIN [#Domain\#Username] FROM WINDOWS';
SET #params = N'#Username NVARCHAR(MAX), #Domain NVARCHAR(MAX)';
END
exec sp_executesql #sql, #params, #Username=#SearchUsername, #Domain=#SearchDomain
END
The problem I am having is that every time this SP is called I get the following error:
Using this data: #SearchDomain = OFFICE and #SearchUsername = BJackson
The problem here is you think SQL is a scripting language; it is not. For example '#Domain' means the literal string '#Domain' not replace the literal string '#Domain' with the value in the variable #Domain.
If you have EXEC sys.sp_executesql N'SELECT '#V1 + #V2';', N'#V1 varchar(30), #V2 varchar(30)','This', 'works'; you don't get the value 'Thisworks' you get the value '#V1 + #V2' Why? Because they are literals.
What you need to do is safely inject your parameters for the object names, and properly parametrise your WHERE:
ALTER PROCEDURE [dbo].[CheckIfSQLLoginExistsAndCreateLogin] --removed prefix
#SearchDomain sysname, --Corrected datatype
#SearchUsername sysname --Corrected datatype
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(max);
DECLARE #Login sysname = CONCAT(#SearchDomain,'\',#SearchUsername);
IF #Login != ''
BEGIN
SET #sql = N'IF NOT EXISTS (SELECT * FROM sys.server_principals WHERE [name] = #Login) CREATE LOGIN ' + QUOTENAME(Login) + N' FROM WINDOWS';
END
EXEC sys.sp_executesql #sql, N'#Login sysname', #Login;
END;
Here is a simple example:
CREATE OR ALTER PROCEDURE [dbo].[sp_CheckIfSQLLoginExistsAndCreateLogin]
#SearchDomain NVARCHAR(MAX),
#SearchUsername NVARCHAR(MAX)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(max);
DECLARE #params NVARCHAR(MAX);
IF #SearchUsername != ''
BEGIN
SET #sql = N'IF NOT EXISTS (SELECT * FROM sys.server_principals WHERE [name] = '''+ #SearchDomain +'\'+ #SearchUsername +''') CREATE LOGIN [#Domain\#Username] FROM WINDOWS';
SET #params = N'#Username NVARCHAR(MAX), #Domain NVARCHAR(MAX)';
END
exec sp_executesql #sql, #params, #Username=#SearchUsername, #Domain=#SearchDomain
END

How to store a query result in a variable

SQL Server stored procedure:
CREATE PROCEDURE [dbo].[CheckTableStatus]
#DatabaseName AS NVARCHAR(50) = 'DBA',
#ProjectID AS NVARCHAR(50) = 'CommandLog'
AS
BEGIN
SET NOCOUNT ON;
DECLARE #TableCount as int
SET #Temp = 'DECLARE #cnt as int;'
SET #Temp = #Temp + 'USE '+ #DatabaseName +'; SELECT #cnt=COUNT(TABLE_NAME) FROM INFORMATION_SCHEMA.Tables WHERE TABLE_NAME=''' + #ProjectID + ''';'
PRINT #Temp
EXEC sp_executesql #temp
--ASSIGN OUTPUT TO #TableCount
IF #TableCount > 0
-- Do something
END
How do I assign the results of #temp being executed to variable #TableCount?
If your goal is to get the count from #temp, try using an OUTPUT with your dynamic SQL:
EXEC sp_executesql #temp, N'#cnt int OUTPUT', #TableCount OUTPUT
These additions to sp_executesql will output the #cnt value in your dynamic SQL to the #TableCount in your current context.
Use the OUTPUT parameter:
CREATE PROCEDURE [dbo].[CheckTableStatus]
#DatabaseName as nvarchar(50) = 'DBA',
#ProjectID as nvarchar(50) = 'CommandLog'
AS
BEGIN
SET NOCOUNT ON;
DECLARE #TableCount as int,#Temp nvarchar(max)='';
-- SET #Temp = 'DECLARE #cnt as int;'
SET #Temp = #Temp + 'USE '+ #DatabaseName +'; SELECT #cnt=COUNT(TABLE_NAME) FROM INFORMATION_SCHEMA.Tables WHERE TABLE_NAME=''' +
#ProjectID + ''';'
print #Temp
EXEC sp_executesql #temp,
N'#cnt int out',#TableCount out;
--ASSIGN OUTPUT TO #TableCount
IF #TableCount >0
-- Do something
print #TableCount;
END
But why not use the OBJECT_ID function?
Also your code is prone to SQL-injection.
You can set value as
SET #TableCount = #cnt

insert data in dynamic table

i am usginf this but getting error can u provide a solution.
DECLARE #TableName VARCHAR(500);
SET #TableName = N'CREATE TABLE businessmaster_'+
CONVERT(VARCHAR(10),GetDate()-1,112)+
N' ( contentid int,Businessname varchar(50) )';
print #TableName
declare #sql varchar(100)
SET #sql = 'INSERT INTO'+ #TableName+' (contentid,Businessname) SELECT top 10 contentid,Businessname FROM businessmaster';
EXEC (#sql);
You did not create the table, it should look like this
DECLARE #TableName VARCHAR(500);
SET #TableName = N'businessmaster_'+CONVERT(VARCHAR(10),GetDate()-1,112);
EXEC (N'CREATE TABLE '+#TableName +' ( contentid int,Businessname varchar(50) )')
print #TableName
declare #sql varchar(100)
SET #sql = 'INSERT INTO '+ #TableName+' (contentid,Businessname) SELECT top 10 contentid,Businessname FROM businessmaster';
EXEC (#sql)
You did not create your table, how can you insert data to table not exist:
DECLARE #TableName VARCHAR(MAX);
DECLARE #SQL NVARCHAR(MAX);
SET #TableName = N'businessmaster_'+
CONVERT(VARCHAR(10),GetDate()-1,112);
SET #SQL = N' CREATE TABLE '+#TableName + N' ( contentid int,Businessname varchar(50) )';
EXECUTE (#SQL);
SET #SQL = 'INSERT INTO '+ #TableName+' (contentid,Businessname) SELECT top 10 contentid,Businessname FROM businessmaster';
EXECUTE (#SQL);
Demo.

MS SQL Stored Procedure for counting Dynamic table items

I had wrote this below stored procedure and getting incorrect statement.
ALTER PROCEDURE dbo.[Counter]
#TableName VARCHAR(100)
AS
BEGIN
DECLARE #Counter INT
DECLARE #SQLQ VARCHAR(200)
SET NOCOUNT ON;
--SET #TableName = 'Member';
SET #SQLQ = 'SELECT COUNT(*) FROM dbo.[' + #TableName + ']';
--Preparing the above sql syntax into a new statement(get_counter).
--Getting an error here I had googled the prepare statement but don't know why facing this error.
PREPARE get_counter FROM #SQLQ;
#Counter = EXEC get_counter; -- here #resutl gets the value of the count.#TableName
DEALLOCATE PREPARE get_counter; -- removing the statement from the memory.
END
Then I had wrote another one:
ALTER PROCEDURE dbo.[Counter]
#TableName VARCHAR(100)
AS
BEGIN
DECLARE #Counter INT
DECLARE #SQLQ VARCHAR(200)
SET NOCOUNT ON;
--SET #TableName = 'Member';
SET #SQLQ = 'SELECT COUNT(*) FROM dbo.[' + #TableName + ']';
--Preparing the above sql syntax into a new statement(get_counter).
Execute #SQLQ; -- here #resutl gets the value of the count.#TableName
--DEALLOCATE PREPARE get_counter; -- removing the statement from the memory.
Return #Counter;
END
It is running fine but I can't get the result in the Counter , anyone please help me(I know that I haven't assigned any value to the counter but if I do I get error).
After your answer martin I had replace my code with yours now its :
ALTER PROCEDURE dbo.[Counter] #SchemaName SYSNAME = 'dbo' , #TableName SYSNAME
AS
BEGIN
SET NOCOUNT ON;
DECLARE #SQLQ NVARCHAR(1000)
DECLARE #Counter INT;
SET #SQLQ = 'SELECT #Counter = COUNT(*) FROM ' +
Quotename(#SchemaName) + '.' + Quotename(#TableName);
EXEC sp_executesql
#SQLQ ,
N'#Counter INT OUTPUT',
#Counter = #Counter OUTPUT
Return SELECT #Counter
END
Now I had retrieved it .
ALTER PROCEDURE dbo.[CreateBusinessCode]
#MemberID bigint,
#len int,
#RewardAccountID bigint,
#ConnectionStatusID tinyint,
#Assign smalldatetime
AS
BEGIN
SET NOCOUNT ON;
DECLARE #counter INT
EXEC #counter = dbo.Counter 'dbo','member';
Select #counter;
END
You should use SYSNAME for object identifiers and Quotename rather than concatenating the square brackets yourself.
ALTER PROCEDURE dbo.[Counter] #TableName SYSNAME,
#SchemaName SYSNAME = 'dbo'
AS
BEGIN
SET NOCOUNT ON;
DECLARE #SQLQ NVARCHAR(1000)
DECLARE #Counter INT;
SET #SQLQ = 'SELECT #Counter = COUNT(*) FROM ' +
Quotename(#SchemaName) + '.' + Quotename(#TableName);
EXEC sp_executesql
#SQLQ ,
N'#Counter INT OUTPUT',
#Counter = #Counter OUTPUT
SELECT #Counter
END
In SQL Server, if you want to get a result into a variable, you have two choices.
The first is to use cursors.
The second is to do dynamic SQL:
declare #sql varchar(max) = whatever;
declare #cnt int;
declare #cntTable table as (cnt int);
insert into #cntTable
exec(#sql);
select #cnt = t.cnt
from #cntTable
It is cumbersome, but one or the other does work.
try this one.It doesnt query the actual table but will provide you the count of rows.This is better way if you have large tables and you need approximate count.
ALTER PROCEDURE dbo.[Counter]
#TableName VARCHAR(100)
AS
begin
declare #objectid int,#counter int
select #objectid = object_id from sys.all_objects where name = #tablename and schema_id=SCHEMA_ID('dbo')
select #counter = sum(rows) from sys.partitions where object_id= #objectid
and index_id in (0,1)
select #counter
end
go