I want to create a stored procedure which updates table column based on sent condition. The queries which i wrote dont work.
First is if I try to set Table name as variable.
Create Procedure Proc_Test
#Tblname varchar(20)
AS BEGIN
Update #Tblname
Set IsValid = 1;
End
this fails.
Second I have tried is case statement
Create Procedure Proc_Test
#Tblname varchar(20)
AS BEGIN
Case #Tblname
WHEN 1 THEN Update tbl1 set ISValid = 1;
WHEN 2 THEN Update tbl2 set ISValid = 1;
End
END
This also throws exception.
Any other way to achieve this ?
You need to use dynamic sql if you want the table name to be variable, otherwise you need to use conditional statements to filter based on table names, which would be ok if there weren't too many table names to work through.
Conditional Approach
declare #Tblname varchar(20) = 'Table1'
if #Tblname = 'Table1'
begin
update Table1
set IsValid = 1
-- where some condition is met?
end
if #Tblname = 'Table2'
begin
update Table2
set IsValid = 1
-- where some condition is met?
end
Dynamic Sql Approach
declare #SQLString nvarchar(100);
declare #Tblname varchar(20) = 'Table1'
set #SQLString = N'update ' + #Tblname + ' set IsValid = 1';
execute sp_executesql #SQLString
Try this -
CREATE PROCEDURE Proc_Test
#Tblname VARCHAR(20)
AS
BEGIN
DECLARE #SQL varchar(1000);
SET #SQL = 'Update '+#Tblname+' Set IsValid = 1;'
EXECUTE (#SQL);
END
Related
i want to create a new table that has dynamic number of columns depending on the row values of an other table.
For example i have a table (table1) that has 2 columns named 'VALUE' and 'ISACTIVE' ('ISACTIVE' column takes the value 1 if we need to take into account this value as a column in the new table) and i need to create a new table that has:
number of columns (and column name) of new table = the values of table1 where Isactive = 1.
Try out the below.This is assuming all the columns to be integer .we can modify accordingly if it is varchar .We need to alter the existing table and add a column called textval which defaults to '0' here
drop table test
create table test
(
value integer,
isactive integer
);
alter table test add textval nvarchar(max) default '0'
insert into test (value,isactive) values (123,5);
select * from test;
Now update the new columns based on the value of isactive .if it is 5 the new column will have upto col5 all beign integer and use this to create a new table
begin
declare #i integer;
set #i=1
declare #isactive integer;
declare #stmt nvarchar(max);
declare #stmt2 nvarchar(max);
declare #testval nvarchar(max);
set #isactive= (select isactive from test)
while (#i <=#isactive)
begin
declare #textval nvarchar(max);
set #textval = (select textval from test)
set #stmt= 'update test set textval = '''+ #textval +'col' +cast(#i
as varchar(100)) + ' ' + 'integer,'''
execute sp_executesql #statement=#stmt
set #i=#i+1;
end
set #testval=(select left(replace(textval,'0col1','col1'),len(textval)-2)
from test)
set #stmt2 ='create table tab1 ( ' + #testval + ' )';
execute sp_executesql #statement=#stmt2;
end
My first thought was to create it dynamically in a procedure based on your conditions. Read this question and answers , it will help.
T-SQL How to create tables dynamically in stored procedures?
Raw example
DECLARE #SQLString NVARCHAR(MAX)
SET #SQLString = N'CREATE TABLE <table_name> ('
-- Conditons here
SET #SQLString = #SQLString + '<column_name> <type>'
-- End of conditions
SET #SQLString = #SQLString + ')'
EXEC (#SQLString)
SELECT [attributeName] INTO [DatabaseName].[dbo].[NewTableName]
FROM [DatabaseName].[dbo].[FromTableName] WHERE ISACTIVE=1
I'm facing deadlock
was deadlocked on lock resources with another process and has been
chosen as the deadlock victim.
problem In SQL-Server as i'm inserting data in database by picking max id against a specific column then add a increment got the value against which record will be inserted.
i'm calling a procedure as code mentioned below:
CREATE
PROCEDURE [dbo].[Web_GetMaxColumnID]
#Col_Name nvarchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
DECLARE #MaxID BIGINT;
SET NOCOUNT ON;
-- Insert statements for procedure here
BEGIN
BEGIN TRAN
SET #MaxID = (
SELECT Col_Counter
FROM Maintenance_Counter WITH (XLOCK, ROWLOCK)
WHERE COL_NAME = #Col_Name
)
UPDATE Maintenance_Counter
SET Col_Counter = #MaxID + 1
WHERE COL_NAME = #Col_Name
COMMIT
END
SELECT (
CONVERT(
VARCHAR,
(
SELECT office_id
FROM Maintenance
)
) + '' + CONVERT(VARCHAR, (#MaxID))
) AS MaxID
END
any one help me out .....
As Marc already answered, use SEQUENCE. It's available in all supported versions of SQL Server, ie 2012 and later. The only reason to avoid it is targeting an unsupported version like 2008.
In this case, you can set the counter variable in the same statement you update the counter value. This way, you don't need any transactions or locks, eg:
declare #counterValue bigint
UPDATE Maintenance_Counter
SET Col_Counter = Col_Counter + 1 , #counterValue=Col_Counter+1
WHERE COL_NAME = #Col_Name
select #counterValue
Yo can use sequences to generate incremental values avoiding any blocking.
I have adapted my own Counter Generator to be a direct replacement for yours. It creates dynamically the SQL statements to manage sequences, if a Sequence doesn't exist for the value we are looking for, it creates it.
ALTER PROCEDURE [dbo].[Web_GetMaxColumnID]
#Col_Name nvarchar(50)
AS
declare #Value bigint;
declare #SQL nvarchar(64);
BEGIN
if not exists(select * from sys.objects where object_id = object_id(N'dbo.MY_SEQUENCES_' + #Col_Name) and type = 'SO')
begin
set #SQL = N'create sequence dbo.MY_SEQUENCES_' + #Col_Name + ' as bigint start with 1';
exec (#SQL);
end
set #SQL = N'set #Value = next value for dbo.MY_SEQUENCES_' + #Col_Name;
exec sp_executesql #SQL, N'#Value bigint out', #Value = #Value out;
select #Value ;
END
The only inconvenience is that your values can get gaps within (because you could have retrieved a value but finally not used it). This is not a problem on my tables, but you have to consider it.
I try to select data from a table of another database in my storedprocedure and the name of the other database is given by parameter. I get an error message:
'Invalid object name [#DbName].dbo.Setup'.
CREATE PROCEDURE [dbo].[spUndeliverableOrders]
#DbName sysname
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Sortfield nvarchar(50)
SET #Sortfield = (SELECT COALESCE(Text, 'ToDoListeDatum') AS SortField FROM [#DbName].dbo.Setup WHERE label like 'ComboBoxSetupBatchReihenfolge')
END
GO
Can someone help me to solve this problem?
Like #ThomasSchremser said:
DECLARE #sqlquery varchar(1000)
SET #sqlquery = '(SELECT COALESCE(Text, ''ToDoListeDatum'') AS SortField FROM ['+#DbName+'].dbo.Setup WHERE label like ''ComboBoxSetupBatchReihenfolge'')'
It is upto you to decide weither you what to populate a table/variable with the results.
Either use:
insert into #table(column) exec #sqlquery...
or
sp_executesql #sqlquery...
You need to use dynamic query as below
CREATE PROCEDURE [dbo].[spUndeliverableOrders]
#DbName sysname
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #Str varchar(max)
CREATE TABLE #Result(Res VARCHAR(MAX))
SET #Str = 'insert into #Result SELECT TOP 1 COALESCE(Text, ''ToDoListeDatum'') AS SortField FROM ['+#DbName+'].dbo.Setup WHERE label like ''ComboBoxSetupBatchReihenfolge'''
exec(#str)
select Res from #Result
END
Modified per your script:
DECLARE #Str varchar(max)
CREATE TABLE #Result(Res VARCHAR(MAX))
SET #Str = ' SELECT TOP 1 COALESCE(Text, ''ToDoListeDatum'') AS SortField FROM ['+#DbName+'].dbo.Setup WHERE label like ''ComboBoxSetupBatchReihenfolge'''
insert into #Result
EXEC(#Str)
I am passing dynamically generated query (stored in a variable) to exists() function but it is not working.
SET #TABLE ='MYTABLE'
SET #QUERY='SELECT * FROM '+#TABLE
IF(EXISTS(#QUERY)) PRINT 'RECORD EXISTS'
I have tried this too
--IF(EXISTS(EXEC(#QUERY))) PRINT 'RECORD EXISTS'
You cannot pas a variable like that to the exist funtion.
All you can do is build dynamic sql and check if the rowcount after.
declare #table nvarchar(20)
declare #query nvarchar(200)
SET #TABLE = 'MYTABLE'
SET #QUERY = 'SELECT * FROM ' + #TABLE
EXECUTE sp_executesql #query
IF ##rowcount > 0
print 'record exists'
The problem with this method is that the resultset of #query will also be retrieved.
You can try fixing that like this :
declare #table nvarchar(20)
declare #query nvarchar(200)
SET #TABLE = 'MYTABLE'
SET #QUERY = 'if exists (SELECT * FROM ' + #TABLE + ') print ''record exists'''
EXECUTE sp_executesql #query
EDIT: the OP needs this in a function where you cannot call a procedure:
SQL Server does not allows calling procedures in a function.
A workaround can be to add a integer variable in you function (#tablenumber int) and use it like this :
if #tablenumber = 0
begin
if exists(select * from table1) print 'record exists'
end
else if #tablenumber = 1
begin
if exists(select * from table2) print 'record exists'
end
and so on
This will work if the number of tables is not to big. (it will still work but the maintenance needed is not worth it)
Hi I am writing a large stored procedure, which creates a dynamic report table, of n columns in size, the first 6 are constant the remainder depend on a few arguments passed to the procedure to create the table with the required columns.
The problem that I am having is with the following TSQL
DECLARE #columnname VARCHAR(50)
SET #columnname = 'on_' + #description
IF NOT EXISTS(SELECT * FROM syscolumns WHERE id = OBJECT_ID('reports')
AND NAME = #columnname)
BEGIN
ALTER TABLE reports ADD #columnname VARCHAR(50) NULL
END
I am getting syntax errors with this at the #columnname in the ALTER TABLE statement of the above code.
Also as I am new to this, I am not sure if this is the best way to do this, or if there are better ways in TSQL to generate the required dynamic table.
Try this:
declare #sql nvarchar(100)
set #sql = 'ALTER TABLE reports ADD '+ #columnname+' VARCHAR(50) NULL'
exec sp_executesql #sql
Try
DECLARE #columnname VARCHAR(50)
SET #columnname = '[on_' + #description +']'
IF NOT EXISTS(SELECT * FROM syscolumns WHERE id = OBJECT_ID('reports')
AND NAME = #columnname)
BEGIN
ALTER TABLE reports ADD #columnname VARCHAR(50) NULL
END
Cannot get around having to do it dynamically I believe so change your BEGIN block to something like this:
DECLARE #sql VARCHAR(8000)
BEGIN
SET #sql = 'ALTER TABLE Table_1 ADD '+#columnname+' VARCHAR(50) NULL'
EXEC(#sql)
END