SQL:How to create SQL table using some condition [Create table only when condition is true] - sql

Create table tblname if(name='stack').
Create this table only when this condition is true , So how to write this type of query?

I am not an expert...YET!
But you can try the below query with a IF statement In Another If Statment.
It's Difficult to help if we don't know what your end goal is??
DECLARE #Condition Varchar(5) = 'TRUE'
IF(#Condition='True')
BEGIN
IF NOT EXISTS (SELECT object_id FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[Country]') AND type = 'U')
BEGIN
CREATE TABLE [dbo].Country(ID INT, Description Varchar(20))
END
END;
ELSE
BEGIN
PRINT 'IGNORE - DONT CREATE TABLE'
END;

Related

There is already an object named '#BaseData' in the database

Below is a snippet of my code.
I am wanting to filter my data based upon a variable.
When I try to run the code, it returns an error of "There is already an object named '#BaseData' in the database.". I am not sure as to why this is the case; I have put extra checks within the IF statements to drop the temp table if it already exists but to no avail.
Are you able to help or provide an alternative solution please?
DECLARE #Variable AS VARCHAR(20) = 'Example1'
IF OBJECT_ID(N'TEMPDB..#BaseData') IS NOT NULL
DROP TABLE #BaseData
IF #Variable = 'Example1'
BEGIN
SELECT
*
INTO
#BaseData
FROM
[Database].[schema].[table]
END
IF #Variable = 'Example2'
BEGIN
SELECT
*
INTO
#BaseData
FROM
[Database].[schema].[table]
WHERE
[column] = 1
END
IF #Variable = 'Example3'
BEGIN
SELECT
*
INTO
#BaseData
FROM
[Database].[schema].[table]
WHERE
[column] = 0
END
While code is compiled by SQL, creation of same #table is found in each condition so it doesn't work.
One possible solution would be to create table and than insert data conditionally.
-- DROP TEMP TABLE IF EXISTS
IF OBJECT_ID(N'TEMPDB..#BaseData') IS NOT NULL
DROP TABLE #BaseData
GO
-- CRATE TEMP TABLE WITH TempId, AND SAME STRUCTURE AS YOUR TABLE
SELECT TOP 0 CONVERT(INT, 0)TempId, * INTO #BaseData FROM TestTable
-- DECLARE VARIABLE
DECLARE #Variable AS VARCHAR(20)= 'Example1'
-- INSERT DATA IN TABLE DEPENDING FROM CONDITION
IF (#Variable = 'Example1')
BEGIN
INSERT INTO #BaseData SELECT * FROM TestTable
END
IF (#Variable = 'Example2')
BEGIN
INSERT INTO #BaseData SELECT * FROM TestTable WHERE Id = 1
END
IF (#Variable = 'Example3')
BEGIN
INSERT INTO #BaseData SELECT * FROM TestTable WHERE Id = 2
END

Switch case with storing results into same table in SQL

I want to store the results into table with same name as per the condition. How to achieve the same ? Following is the code:
While executing it throws error that #a already exists.
IF #Input ='1'
BEGIN
drop #a
SELECT *
INTO #a
FROM table1
END;
ELSE IF #Input ='2'
BEGIN
drop #a
SELECT *
INTO #a
FROM table2
END;
You can use this solution using a global temporary table (maybe not the best / safest solution). The statements get executed with EXECUTE:
DECLARE #Input VARCHAR(20) = '1'
IF OBJECT_ID('tempdb..##a') IS NOT NULL
BEGIN
DROP TABLE ##a
END
IF #Input = '1'
EXEC ('SELECT * INTO ##a FROM table1;')
ELSE IF #Input = '2'
EXEC ('SELECT * INTO ##a FROM table2;')
-- you can implement steps here to create a local temporary table.
-- see: https://stackoverflow.com/questions/9534990/tsql-select-into-temp-table-from-dynamic-sql
SELECT * FROM ##a
Also have a look at this question: TSQL select into Temp table from dynamic sql. There is also described how you can get the data as local temporary table in two different ways (using a global temporary table or a view).
The problem using the EXECUTE function is leaving the scope.
try this
if object_id('tempdb..#a') is not null
drop table #a
IF #Input ='1'
BEGIN
SELECT *
INTO #a
FROM table1
END;
ELSE IF #Input ='2'
BEGIN
SELECT *
INTO #a
FROM table2
END;

How to pass name of temp table created in main sp to inner sp in sql?

These are sample tables
UserDetails : id,UserName,IsShow
Brand : id,BrandName
Product : id,ProductName
BrandProduct:id,brandid,productid,price
If Isshow is false, show entire price else hide second -fourth digit.(Price is 5 digits)
create procedure Sp_Details
#brandid int,
#productid int,
#IsShow bit
as
begin
select SomeColumns
into #tableForMechanism
from SomeData
if #IsShow = 0 then
begin
select SomeColumns from #tableForMechanism
end
else
begin
-- Here want to pass table name created by this sp now
-- So can check that table is exist.
-- Because Inner sp is generic.From next 20 sp,have to call
-- same sp.That's why can't give same temp table name because
-- their structure may be different
exec innerDetailsProcedure
end
end
go
create procedure innerDetailsProcedure
#tablename varchar(2000)
as
begin
if OBJECT_ID(#tablename) is NULL
begin
raiserror('Table for mechanism is not created', 16, 1)
return -1
end
else
begin
--update that table
update #tablename
set price = REPLACE(Price, (SUBSTRING(Price,2, 3*#Isshow)), 'xxx')
end
end
What is size of name of temp table created?How to fetch temp table created by this sp now for this session?
So you want to inside a proc check if a #temp table exists, based on a table name that you have in a parameter to that proc? If so, see below. You have to prefix with the database name tempdb in your check with OBJECT_ID():
CREATE PROC p #t1 sysname ,#t2 sysname AS IF OBJECT_ID('tempdb..' + #t1) IS NOT NULL PRINT '#t1 exists'
IF OBJECT_ID('tempdb..' + #t2) IS NOT NULL PRINT '#t2 exists' GO
CREATE TABLE #t(c1 int)
EXEC p #t1 = '#t', #t2 = '#doesntexist'

Conditional SQL statement - conditioning on column to be returned

I'm trying to make a conditional select statement, and the parameter I'm conditioning on is the column I want to return. Meaning - if something about a column in a table is true, I want to return that column; if not, I want to return the other column.
Ex:
IF table.obj_param_A = ?
BEGIN
SELECT obj_param_A FROM table
END
ELSE
BEGIN
SELECT obj_param_B FROM table
END
I know this doesn't work, but it's the general idea of what I want. Any idea how to structure this properly?
If you do not concern the column name returned, you can use CASE
SELECT
CASE
WHEN obj_param_A = ? THEN obj_param_A
ELSE obj_param_B
END AS value
FROM table
Below is an example of how you can use the table information about a specific column in order to select from specific columns.
Drop Table dbo.Test
Create Table dbo.Test (iVersion int, iVersion2 smallmoney)
Insert Into dbo.Test
Select 1, 1.12
Declare #Test as nvarchar(200)
Select #Test = Column_Name from information_schema.columns where Table_Schema = 'dbo' and table_name = 'test' and Ordinal_Position = 1
--IF (#Test = 'iVersion') --Equal To iVersion
IF (#Test != 'iVersion') ---Not Equal To iVersion
BEGIN
SELECT iVersion FROM dbo.Test
END
ELSE
BEGIN
SELECT iVersion2 FROM dbo.Test
END
This should return the data from iVersion2 since the Name of the First column is "iVersion" and the If Statement returns iVersion only if it is not the first column

How can I check if the table behind a synonym exists

I'm trying to create a simple script to dump the results of a complex view out into a table for reporting. I have used synonyms to simplify tweaking the view and table names.
The idea is that the user of the script can put the name of the view they want to use as the source, and the name of the target reporting table in at the start and away they go. If the table doesn't exist then the script should create it. If the table already exists then the script should only copy the records from the view which aren't already in the table over.
The script below covers all those requirements, but I can't find a nice way to check if the table behind the synonym already exists:
CREATE SYNONYM SourceView FOR my_view
CREATE SYNONYM TargetReportingTable FOR my_table
-- Here's where I'm having trouble, how do I check if the underlying table exists?
IF (SELECT COUNT(*) FROM information_schema.tables WHERE table_name = TargetReportingTable) = 0
BEGIN
-- Table does not exists, so insert into.
SELECT * INTO TargetReportingTable FROM SourceView
END
ELSE
BEGIN
-- Table already exists so work out the last record which was copied over
-- and insert only the newer records.
DECLARE #LastReportedRecordId INT;
SET #LastReportedRecordId = (SELECT MAX(RecordId) FROM TargetReportingTable)
INSERT INTO TargetReportingTable SELECT * FROM SourceView WHERE RecordId > #LastReportedRecordId
END
DROP SYNONYM SourceView
DROP SYNONYM TargetReportingTable
I know I could just get the user of the script to copy the table name into the 'information_schema' line as well as into the synonym at the top, but that leaves scope for error.
I also know I could do something filthy like put the table name into a variable and blat the SQL out as a string, but that makes me feel a bit sick!
Is there a nice elegant SQL way for me to check if the table behind the synonym exists? Or a totally different way to solve to problem?
Not the most elegant of solutions, but you could join the sys.synonyms table to the sys.tables table to check whether the table exists.
If the table does not exist, the join will fail and you will get 0 rows (hence IF EXISTS will be false). If the table does exist, the join will success and you will get 1 row (and true):
IF EXISTS( SELECT *
FROM sys.synonyms s
INNER JOIN sys.tables t ON REPLACE(REPLACE(s.base_object_name, '[', ''), ']', '') = t.name
WHERE s.name = 'TargetReportingTable')
BEGIN
-- Does exist
END
ELSE
BEGIN
-- Does not exist
END
Replace 'TargetReportingTable' with whichever synonym you wish to check.
The above solutions did not work for me if the synonym referenced another database. I recently discovered the function [fn_my_permissions] which is useful for showing permissions for a specific database object, so I figure this could be used as follows:
IF EXISTS
(
select *
from sys.synonyms sy
cross apply fn_my_permissions(sy.base_object_name, 'OBJECT')
WHERE sy.name = 'TargetReportingTable'
)
print 'yes - I exist!'
Late to the party, I have created a query to test out the existence of Synonyms and share with you.
DECLARE #Synonyms table
(
ID int identity(1,1),
SynonymsDatabaseName sysname,
SynonymsSchemaName sysname,
SynonymsName sysname,
DatabaseName nvarchar(128),
SchemaName nvarchar(128),
ObjectName nvarchar(128),
Remark nvarchar(max),
IsExists bit default(0)
)
INSERT #Synonyms (SynonymsDatabaseName, SynonymsSchemaName, SynonymsName, DatabaseName, SchemaName, ObjectName)
SELECT
DB_NAME() AS SynonymsDatabaseName,
SCHEMA_NAME(schema_id) AS SynonymsSchemaName,
name AS SynonymsName,
PARSENAME(base_object_name,3) AS DatabaseName,
PARSENAME(base_object_name,2) AS SchemaName,
PARSENAME(base_object_name,1) AS ObjectName
FROM sys.synonyms
SET NOCOUNT ON
DECLARE #ID int = 1, #Query nvarchar(max), #Remark nvarchar(max)
WHILE EXISTS(SELECT * FROM #Synonyms WHERE ID = #ID)
BEGIN
SELECT
#Query = 'SELECT #Remark = o.type_desc FROM [' + DatabaseName + '].sys.objects o INNER JOIN sys.schemas s ON o.schema_id = s.schema_id WHERE s.name = ''' + SchemaName + ''' AND o.name = ''' + ObjectName + ''''
FROM #Synonyms WHERE ID = #ID
EXEC sp_executesql #Query, N'#Remark nvarchar(max) OUTPUT', #Remark OUTPUT;
UPDATE #Synonyms SET IsExists = CASE WHEN #Remark IS NULL THEN 0 ELSE 1 END, Remark = #Remark WHERE ID = #ID
SELECT #ID += 1, #Remark = NULL
END
SELECT * FROM #Synonyms
You can do this with dynamic SQL:
-- create synonym a for information_schema.tables
create synonym a for b
declare #exists int = 1;
begin try
exec('select top 0 * from a');
end try
begin catch
set #exists = 0;
end catch
select #exists;
This doesn't work with non-dynamic SQL, because the synonym reference is caught at compile-time. That means that the code just fails with a message and is not caught by the try/catch block. With dynamic SQL, the block catches the error.
You can test if Synonym exists in your database using the Object_Id function avaliable in SQL Server
IF OBJECT_ID('YourDatabaseName..YourSynonymName') IS NOT NULL
PRINT 'Exist SYNONYM'
ELSE
PRINT 'Not Exist SYNONYM'
Another simpler solution:
IF (EXISTS (SELECT * FROM sys.synonyms WHERE NAME ='mySynonymName'))
BEGIN
UPDATE mySynonymName
SET [Win] = 1
END
In this case, I do database setup first. I drop all Synonyms in my database (database1) first, then run a SPROC to create synonyms for all tables in the destination database(database2).
Some SPROCS in database1 call on tables in DB2. If table doesnt exist in DB2 the SPROC fails. If table doesnt exist in DB2, the synonmy is not automatically created on database setup. So I just use the above to check if the Synonym exist, and skip that part of the SPROC if the Synonym is not present.