I am in the process of writing a pretty large query that selects from multiple tables and unions them. Because of some really poor database design, a table is created for every user.
What I am doing is something like this:
SELECT *
FROM tbl1
UNION ALL
SELECT *
FROM tbl2
What I am looking for is something generic to add to each line that will enable me to select the table name along with what's inside the table.
I won't accept the below as an answer, because that is not what I've asked for.
SELECT *, 'tbl1'
FROM tbl1
UNION ALL
SELECT *, 'tbl2'
FROM tbl2
To do something like that you either have to make some rather complex and large query into the system views (sys.tables and sys.columns)
But you're properly better off building the query dynamically in what ever code lanuage you use and execute it as a string:
A very rough example could be something like
DECLARE #tableName varchar(255) = 'tbl1';
DECLARE #tableName2 varchar(255) = 'tbl2';
DECLARE #columnList varchar(255) = 'Col1, Col2, Col3';
EXEC(
'SELECT '+ #columnList +' FROM ' +#tableName + '
UNION ALL
SELECT '+ #columnList +' FROM ' +#tableName2
);
Before each select from the table add a SELECT NULL, NULL, 'tableName'; (add as many NULL as table columns so that union all doesn't 'fail'. Or Instead of NULL use '-' or whatever.
I guess the tables looping and obtaining the column names shouldn't be an issue..
Below demo:
create table #t1(C1 int, C2 int)
create table #t2(C1 int, C2 int)
insert #t1 (C1, C2) values (1,2)
insert #t2 (C1, C2) values (3,4)
insert #t2 (C1, C2) values (5,6)
declare #t1 varchar(10) = '#t1';
declare #t2 varchar(10) = '#t2';
declare #cols varchar(100) = 'C1, C2';
declare #sql nvarchar(4000) = ''
set #sql =
' SELECT NULL, NULL, ''' + #t1 + ''' ' + char(10) + char(13) +
' UNION ALL ' + char(10) + char(13) +
' SELECT '+ #cols +', NULL FROM ' + #t1 + char(10) + char(13) +
' UNION ALL ' + char(10) + char(13) +
' SELECT NULL, NULL, ''' + #t2 + ''' ' + char(10) + char(13) +
' UNION ALL ' + char(10) + char(13) +
' SELECT '+ #cols +', NULL FROM ' + #t2
-- select #sql
exec (#sql);
In production code you already need to construct a query that has FROM table_name so you should just add that table name in as a projected column at the same time.
Technically there is a way of doing this in versions that support dm_db_page_info though but this would be very inefficient and require elevated permissions.
CREATE TABLE dbo.T(X INT);
INSERT INTO T VALUES (1),(2),(3);
SELECT OBJECT_NAME(pg_info.object_id) AS table_name, T.*
FROM dbo.T
CROSS APPLY sys.fn_PhysLocCracker(%%physloc%%) pl
CROSS APPLY sys.dm_db_page_info(db_id(), pl.file_id, pl.page_id, 'LIMITED') pg_info
Returns
+------------+---+
| table_name | X |
+------------+---+
| T | 1 |
| T | 2 |
| T | 3 |
+------------+---+
Related
I have a single sql instance with many databases.
In a single query I want to count the rows of two tables in each database, Shops and Locations, to be able to compare the values.
So far I have the following query:
SELECT ('SELECT COUNT(1) FROM [' + name + '].[abc].[Shops]') as shopCount,
('SELECT COUNT(1) FROM [' + name + '].[def].[Locations]') as locationCount,
name as DB
FROM sys.databases
WHERE OBJECT_ID('[' + name + '].[abc].[Shops]') IS NOT NULL AND
OBJECT_ID('[' + name + '].[def].[Locations]' ) IS NOT NULL
Which results in the following output
shopCount | locationsCount | DB
------------------------------------------------------------------------------------------------------------------
SELECT COUNT(1) FROM [database1].[abc].[Shops] | SELECT COUNT(1) FROM [database1].[def].[Locations] | database1
------------------------------------------------------------------------------------------------------------------
SELECT COUNT(1) FROM [database2].[abc].[Shops] | SELECT COUNT(1) FROM [database2].[def].[Locations] | database2
So pretty obviously, I am not executing the strings as a query but am unable to figure out how to do so.
Something like this:
DECLARE #DynamicTSQLStatement NVARCHAR(MAX);
CREATE TABLE #DataSource
(
[shopCount] INT
,[locationCount] INT
,[database] SYSNAME
);
SET #DynamicTSQLStatement = STUFF
(
(
SELECT ';INSERT INTO #DataSource SELECT (SELECT COUNT(1) FROM [' + name + '].[abc].[Shops]), (SELECT COUNT(1) FROM [' + name + '].[def].[Locations]), ''' + name +''''
FROM sys.databases
WHERE OBJECT_ID('[' + name + '].[abc].[Shops]') IS NOT NULL AND
OBJECT_ID('[' + name + '].[def].[Locations]' ) IS NOT NULL
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1
,1
,''
);
EXEC sp_executesql #DynamicTSQLStatement;
SELECT *
FROM #DataSource;
DROP TABLE #DataSource;
You are trying to do some dynamic sql. Have a read here: http://www.sqlservertutorial.net/sql-server-stored-procedures/sql-server-dynamic-sql/
the first example seems to be what you're looking for.
I am using SQL Server 2012. i have a table with 90 columns. I am trying to select only columns that contains data. After searching i used the following procedure:
1- Getting all columns count using one select query
2- Pivoting Result Table into a Temp table
3- Creating Select query
4- Executing this query
Here is the query i used:
DECLARE #strTablename varchar(100) = 'dbo.MyTable'
DECLARE #strQuery varchar(max) = ''
DECLARE #strSecondQuery varchar(max) = 'SELECT '
DECLARE #strUnPivot as varchar(max) = ' UNPIVOT ([Count] for [Column] IN ('
CREATE TABLE ##tblTemp([Column] varchar(50), [Count] Int)
SELECT #strQuery = ISNULL(#strQuery,'') + 'Count([' + name + ']) as [' + name + '] ,' from sys.columns where object_id = object_id(#strTablename) and is_nullable = 1
SELECT #strUnPivot = ISNULL(#strUnPivot,'') + '[' + name + '] ,' from sys.columns where object_id = object_id(#strTablename) and is_nullable = 1
SET #strQuery = 'SELECT [Column],[Count] FROM ( SELECT ' + SUBSTRING(#strQuery,1,LEN(#strQuery) - 1) + ' FROM ' + #strTablename + ') AS p ' + SUBSTRING(#strUnPivot,1,LEN(#strUnPivot) - 1) + ')) AS unpvt '
INSERT INTO ##tblTemp EXEC (#strQuery)
SELECT #strSecondQuery = #strSecondQuery + '[' + [Column] + '],' from ##tblTemp WHERE [Count] > 0
DROP TABLE ##tblTemp
SET #strSecondQuery = SUBSTRING(#strSecondQuery,1,LEN(#strSecondQuery) - 1) + ' FROM ' + #strTablename
EXEC (#strSecondQuery)
The problem is that this query is TOO SLOW. Is there a best way to achieve this?
Notes:
Table have only one clustered index on primary key Column ID and does not contains any other indexes.
Table is not editable.
Table contains very large data.
Query is taking about 1 minute to be executed
Thanks in advance.
I do not know if this is faster, but you might use one trick: FOR XML AUTO will ommit columns without content:
DECLARE #tbl TABLE(col1 INT,col2 INT,col3 INT);
INSERT INTO #tbl VALUES (1,2,NULL),(1,NULL,NULL),(NULL,NULL,NULL);
SELECT *
FROM #tbl AS tbl
FOR XML AUTO
This is the result: col3 is missing...
<tbl col1="1" col2="2" />
<tbl col1="1" />
<tbl />
Knowing this, you could find the list of columns, which are not NULL in all rows, like this:
DECLARE #ColList VARCHAR(MAX)=
STUFF
(
(
SELECT DISTINCT ',' + Attr.value('local-name(.)','nvarchar(max)')
FROM
(
SELECT
(
SELECT *
FROM #tbl AS tbl
FOR XML AUTO,TYPE
) AS TheXML
) AS t
CROSS APPLY t.TheXML.nodes('/tbl/#*') AS A(Attr)
FOR XML PATH('')
),1,1,''
);
SELECT #ColList
The content of #ColList is now col1,col2. This string you can place in a dynamically created SELECT.
UPDATE: Hints
It would be very clever, to replace the SELECT * with a column list created from INFORMATION_SCHEMA.COLUMNS excluding all not-nullable. And - if needed and possible - types, wich contain very large data (BLOBs).
UPDATE2: Performance
Don't know what your very large data means actually... Just tried this on a table with about 500.000 rows (with SELECT *) and it returned correctly after less than one minute. Hope, this is fast enough...
Try using this condition:
where #columnname IS NOT NULL AND #columnname <> ' '
I'm using a request to get a collection of columns name:
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE [...]
From this collection, I'd like to count every not null, not empty value from the original table group by column name.
Let's say I have a table containing
COL1 | COL2 | COL3
------------------
VAL1 | VAL2 | NULL
VAL3 | | VAL4
VAL5 | |
I'm looking for a request to get:
COL1 | 3
COL2 | 1
COL2 | 1
It's for analytics purpose.
Thanks for your help!
Here is a simple process. Run the following query:
SELECT 'SELECT ''' + COLUMN_NAME + ''', COUNT(['+COLUMN_NAME']) as NotNull FROM [' +SCHEMA_NAME+ '].['+TABLE_NAME+ '] union all '
FROM INFORMATION_SCHEMA.COLUMNS
WHERE [...]
Copy the results into a query window, remove the final union all, and run the query.
The below code seems to work for your issue
create table sample
(
col1 varchar(10),
col2 varchar(10),
col3 varchar(10)
)
INSERT INTO sample (COL1,COL2,COL3) VALUES ('VAL1 ',' VAL2 ',NULL);
INSERT INTO sample (COL1,COL2,COL3) VALUES ('VAL3 ',' ',' VAL4');
INSERT INTO sample (COL1,COL2,COL3) VALUES ('VAL5 ',' ',' ');
DECLARE #cols1 NVARCHAR(MAX);
DECLARE #sql NVARCHAR(MAX);
SELECT #cols1 = STUFF((
SELECT ', COUNT(CASE WHEN len(['+ t1.NAME + '])!=0 THEN 1 END) AS ' + t1.name
FROM sys.columns AS t1
WHERE t1.object_id = OBJECT_ID('sample')
--ORDER BY ', COUNT([' + t1.name + ']) AS ' + t1.name
FOR XML PATH('')
), 1, 2, '');
SET #sql = '
SELECT ' + #cols1 + '
FROM sample
'
EXEC(#sql)
Hereis my little longer take on this:
declare #cols table (colID integer, colName varchar(50))
declare #results table (colName nvarchar(50), valueCount bigint)
-- table name
declare #tableName nvarchar(50) = 'INSERT TABLE NAME HERE'
-- select column names from table
insert into #cols
select column_id, name from sys.columns where object_id = object_id(#tableName) order by column_id
declare #currentColID int = 0
declare #currentName nvarchar(50) = ''
declare #currentCount bigint = 0
declare #sql nvarchar(max) -- where the dynamic sql will be stored
-- go through all columns
while (1 = 1)
begin
-- step by id
select top 1 #currentColID = c.colID, #currentName = c.colName from #cols c
where c.colid > #currentColID order by c.colID
if ##ROWCOUNT = 0 break;
-- dynamic query to get non-empty, not-null counts
select #sql = 'select #p1=COUNT(' + #currentName + ') from ' + #tableName +
' where ' + #currentName + ' is not null or LEN(' + #currentName + ') > 0'
exec sp_executesql #sql, N'#p1 bigint output', #p1 = #currentCount output
-- insert result to buffer
insert into #results values (#currentName, #currentCount)
end
-- print the buffer
select * from #results
Have fun :)
I have a master table in a database.
Example Menu table
+-----------+-----------+-------------+---------+------------------------+
| Id | Key | Display Text| ParentId| CreatedOn
+-----------+-----------+-------------+---------+------------------------+
| 1 | Home | Home | NULL |2014-01-14 21:17:37.387 |
| 2 | About | About Us | NULL |2014-01-14 21:17:37.387 |
| 3 | Contact | Contact Us | NULL |2014-01-14 21:17:37.387 |
+-----------+-----------+------+------+---------+------------------------+
I used to generate master data script like below for each record.
IF NOT EXISTS(SELECT 1 FROM [Menu] WHERE Id=1 AND Key='Home')
BEGIN
SET IDENTITY_INSERT [dbo].[Menu] ON
INSERT INTO [dbo].[Menu]
(Id
,[Key]
,[DisplayText]
,[ParentId]
,[CreatedOn])
VALUES
(1
,'Home'
,'Home'
,NULL
,GETDATE()
)
SET IDENTITY_INSERT [dbo].[Menu] OFF
END
GO
-- Repeating same manual record creation work for all 70 records & other master data(10k rows)
However there is some existing table ApplicationMenu in another database is having same column, datatypes. We would like to generate the below script automatically for us by using some stored procedure.
Is it possible to create a procedure like below
CREATE PROCEDURE spGenerateInsertScripts
(
#SourceTableName VARCHAR(100),
#ExistsWhereClauseTemplate NVARCHAR(1000),
#TargetTableName VARCHAR(100)
)
BEGIN
-- In some loop create those above insert statements
END
We would like to execute like below
exec spGenerateInsertScripts 'ApplicationMenu'
, 'WHERE Id={Id} AND Key={Key}'
, 'Menu'
Here the {Id} & {Key} will be read from every row from existing table and replaced.
This will actually reduce lot of manual work for us.
Note:
We could not use SQL server insert script generation tool, since we want to check the data existence as well as need to keep the records added by user using our application.
Need to generate a insert scripts so that we can just run in future, even when ApplicationTable is not available
Is it possible to write such a procedure to generate insert script from other table based on existence? Like how sql server Generate Scripts work for table creation by looking into INFORMATION_SCHEMA table, same way I am expecting for this.
Final output of the procedure would be like PRINT #insert_Sql_Statements
Your Data
DECLARE #Table TABLE(Id INT, [Key] VARCHAR(30),[Display Text] VARCHAR(30), ParentId INT, CreatedOn DATETIME)
INSERT INTO #Table VALUES
(1,'Home' ,'Home' ,NULL, '2014-01-14 21:17:37.387'),
(2,'About' ,'About Us' ,NULL, '2014-01-14 21:17:37.387'),
(3,'Contact','Contact Us',NULL, '2014-01-14 21:17:37.387')
Query to Create Script
SELECT N'IF NOT EXISTS(SELECT 1 FROM [Menu] WHERE Id='+ CAST(Id AS NVARCHAR(10))
+ ' AND Key='''+ CAST([Key] AS NVARCHAR(1000)) +''')' + CHAR(10)
+ N'BEGIN ' + CHAR(10) + '
SET IDENTITY_INSERT [dbo].[Menu] ON ' + CHAR(10) + '
INSERT INTO [dbo].[Menu] ' + CHAR(10) + '
(Id ' + CHAR(10) + '
,[Key] ' + CHAR(10) + '
,[DisplayText]' + CHAR(10) + '
,[ParentId]' + CHAR(10) + '
,[CreatedOn])' + CHAR(10) + '
VALUES' + CHAR(10) + '
( ' + ISNULL(CAST(Id AS NVARCHAR(10)), 'NULL') + ' ' + CHAR(10) + '
,''' + ISNULL(CAST([Key] AS NVARCHAR(1000)), 'NULL') +''' ' + CHAR(10) + '
,''' + ISNULL(CAST([Display Text] AS NVARCHAR(1000)), 'NULL') + ''' ' + CHAR(10) + '
,' + ISNULL(CAST(ParentId AS NVARCHAR(10)), 'NULL') + ' ' + CHAR(10) + '
,GETDATE() ' + CHAR(10) + '
) ' + CHAR(10) + '
SET IDENTITY_INSERT [dbo].[Menu] OFF ' + CHAR(10) + '
END ' + CHAR(10) + '
GO ' + CHAR(10) + ' '+ CHAR(10)
FROM #Table
Generated Script
╔════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ (No column name) ║
╠════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ IF NOT EXISTS(SELECT 1 FROM [Menu] WHERE Id=1 AND Key='Home') BEGIN SET IDENTITY_INSERT [dbo].[Menu] ON INSERT INTO [dbo].[Menu] (Id ,[Key] ,[DisplayText] ,[ParentId] ,[CreatedOn]) VALUES ( 1 ,'Home' ,'Home' ,NULL ,GETDATE() ) SET IDENTITY_INSERT [dbo].[Menu] OFF END GO ║
║ IF NOT EXISTS(SELECT 1 FROM [Menu] WHERE Id=2 AND Key='About') BEGIN SET IDENTITY_INSERT [dbo].[Menu] ON INSERT INTO [dbo].[Menu] (Id ,[Key] ,[DisplayText] ,[ParentId] ,[CreatedOn]) VALUES ( 2 ,'About' ,'About Us' ,NULL ,GETDATE() ) SET IDENTITY_INSERT [dbo].[Menu] OFF END GO ║
║ IF NOT EXISTS(SELECT 1 FROM [Menu] WHERE Id=3 AND Key='Contact') BEGIN SET IDENTITY_INSERT [dbo].[Menu] ON INSERT INTO [dbo].[Menu] (Id ,[Key] ,[DisplayText] ,[ParentId] ,[CreatedOn]) VALUES ( 3 ,'Contact' ,'Contact Us' ,NULL ,GETDATE() ) SET IDENTITY_INSERT [dbo].[Menu] OFF END GO ║
╚════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
Note
I have got results back in Grid but you can export the results to a file or to text and copy paste it into your query window when you want to execute it.
Assuming I understand your problem correctly, what you're proposing (where clause as a parameter) doesn't sound too good and can cause a WHOLE lot of other issues (e.g. SQL injection, verifying SQL string is in correct format, etc).
How about this approach, which uses linked servers
SET IDENTITY_INSERT [dbo].[Menu] ON
GO
INSERT INTO [dbo].[Menu] ([Id],[Key],[DisplayText],[ParentId],[CreatedOn])
SELECT a.Id, a.Key, a.Key, NULL, GETDATE()
FROM [ApplicationMenu_Instance].[ApplicationMenu_Database].[dbo].[ApplicationMenu] AS a
WHERE NOT EXISTS (
SELECT 1
FROM [dbo].[Menu] AS m
WHERE m.Id = a.Id
AND m.Key = a.Key
)
SET IDENTITY_INSERT [dbo].[Menu] OFF
GO
UPDATE:
Since you want to return the insert script, how about dynamic SQL then:
CREATE PROCEDURE spGenerateInsertScripts
(
#SourceTable VARCHAR(100),
#TargetTable VARCHAR(100)
)
BEGIN
DECLARE #SQL NVARCHAR(MAX) = '
SET IDENTITY_INSERT [dbo].[Menu] ON
GO
INSERT INTO [dbo].[' + #TargetTable + '] ([Id],[Key],[DisplayText],[ParentId],[CreatedOn])
SELECT a.Id, a.Key, a.Key, NULL, GETDATE()
FROM ' + #SourceTable + ' AS a
WHERE NOT EXISTS (
SELECT 1
FROM [dbo].[' + #TargetTable + '] AS m
WHERE m.Id = a.Id
AND m.Key = a.Key
)
SET IDENTITY_INSERT [dbo].[Menu] OFF
GO
';
SELECT #SQL;
END
You can use an SQL statement to generate the required insert statements. You can then just copy and paste the output into wherever you want to execute the query.
Its not a generic solution to creating a script that generates insert statements into one table from another table, but it will dramatically reduce the manual work required for your specific case. You can configure the name of the target table, but the column names and values and the name of the table the data is being retrieved from are hardcoded.
It assumes that the target table entered has the same schema as the table the data is being retrieved from.
DECLARE #TARGET_TABLE AS VARCHAR(100) = '[dbo].[Menu]'
SELECT Script
FROM
(
SELECT Id, [Key], 0 AS [Order],
'IF NOT EXISTS(SELECT 1 FROM ' + #TARGET_TABLE +
' WHERE Id=' + CONVERT(varchar(100), Id) +
' AND Key=''' + [Key] + ''')' AS Script
FROM ApplicationMenu
UNION
SELECT Id, [Key], 1 AS [Order], 'BEGIN' AS Script
FROM ApplicationMenu
UNION
SELECT Id, [Key], 2, 'SET IDENTITY_INSERT ' + #TARGET_TABLE + ' ON'
FROM ApplicationMenu
UNION
SELECT Id, [Key], 3,
'INSERT INTO ' + #TARGET_TABLE +
' VALUES(' +
CONVERT(varchar(11), Id) + ', ''' +
[Key] + ''', ''' +
[DisplayText] + ''', ' +
ISNULL(CONVERT(varchar(11), ParentId), 'NULL') +
', GETDATE())'
FROM ApplicationMenu
UNION
SELECT Id, [Key], 4, 'SET IDENTITY_INSERT ' + #TARGET_TABLE + ' OFF'
FROM ApplicationMenu
UNION
SELECT Id, [Key], 5, 'END'
FROM ApplicationMenu
) AS ScriptInfo
ORDER BY Id, [Key], [Order]
Honestly, the script is a bit painful to look at, but it gets the job done.
If you truly want a generic solution to the problem, you'll probably have more luck implementing it in some sort of programming language (like C#). The upside of implementing it in C# is that you can then import the library into SQL server and call it like a stored procedure (I think, I've never done that sort of thing before).
Additionally there are tools available that will do generate this sort of script for you. If I remember correctly, RedGate SQL Data Compare will do this sort of thing fairly easily. There are probably others.
Take for example this example as an illustration so you can see what Î'm trying to do.
This is how the final table of the pivoted information looks like.
Create Table [#Comparative]
(
Branch char(32),
[2004_January] numeric (18,2),
[2005_January] numeric (18,2),
[2006_January] numeric (18,2),
[2007_January] numeric (18,2),
[2008_January] numeric (18,2),
)
INSERT INTO [#Comparative]
VALUES ('Angeles', NULL, 13550.20, 7820.50, NULL, NULL),
('Detroit', NULL, 13550.20, 7820.50, NULL, NULL),
('New York', NULL, 13550.20, 7820.50, NULL, NULL),
('Arizona', NULL, 13550.20, 7820.50, NULL, NULL)
Select * from [#Comparative]
How could i create a procedure or statement
to drop the set of columns that contains only NULL values taking
into account the columns on the table will be changing as the table is created from other
query that takes information of daily sales to group sum(sales) monthly depending
on the interval of the selected date.
Dynamically create a SQL statement and then run that command. This script drop set of columns with only null values from a temporary table(passed as parameter in SP).
CREATE PROC dbo.dropColumn
#tempTableName nvarchar(100)
AS
BEGIN
DECLARE #dml nvarchar(max) = N''
SELECT #dml += 'IF (SELECT MIN(' + QUOTENAME(c.name) + ') FROM [dbo].' + QUOTENAME(#tempTableName) + ') IS NULL' + CHAR(13) + CHAR(10) +
'BEGIN' + CHAR(13) + CHAR(10) +
' EXEC (''ALTER TABLE [dbo].' + QUOTENAME(#tempTableName) + ' DROP COLUMN ' + QUOTENAME(c.name) + ''')' + CHAR(13) + CHAR(10) +
'END' + CHAR(13) + CHAR(10)
FROM tempdb.sys.tables t JOIN tempdb.sys.columns c ON t.object_id = c.object_id
WHERE t.object_id = OBJECT_ID('[tempdb].[dbo].' + QUOTENAME(#tempTableName))
--PRINT #dml
EXEC sp_executesql #dml
END
EXEC dbo.dropColumn '#Comparative'
Result:
Branch 2005_January 2006_January
----------------------------------------------------------------
Angeles 13550.20 7820.50
Detroit 13550.20 7820.50
New York 13550.20 7820.50
Arizona 13550.20 7820.50
try this : this is one example.
CREATE Stored Procedure.
CREATE PROCEDURE TestSP
(
#IsDroped BIT
)AS
BEGIN
declare #test int
declare #testcount int
set #testcount = (select COUNT(*) from mtp )
set #test = (select distinct 1 from mtp where name is null group by name having COUNT(*)=#testcount )
if #test = 1 AND #IsDroped = 1
begin
alter table mtp drop column name
end
END
Execute this SP
EXEC TestSP 1