how to run Update statement from field in a query - sql

i have a query that returns 1 column
this column is a string containing an update statement
how can i run all updates by runing this query?
SELECT 'UPDATE TOP (' + CAST([Deploy] AS varchar(10)) + ') TRV
SET TRV.SourceStationID = ' + CAST([Station_From] AS varchar(10)) + ',
TRV.MissingStationSourceCode = 888
FROM [Tickets].[dbo].TCK_STG_Fact_Contract_Magnetic_Travels1 TRV
LEFT OUTER JOIN [Tickets].[dbo].[TCK_DWH_Dim_Date] DAT ON CAST(TRV.[ExitDate] AS DATE) = CAST(DAT.Date AS DATE)
LEFT OUTER JOIN [Tickets].[dbo].[TCK_DWH_Dim_Manual_PartOfDay] POD ON DATEPART(HOUR,TRV.[ExitDate]) = POD.PartOfDay_Hour
WHERE DAT.Day_Type_Code = ' + CAST([Day_Type_Code] AS varchar(10)) + '
AND POD.PartOfDay_Code = ' + CAST([PartOfDay_Code] AS varchar(10)) + '
AND TRV.DestinationStation = ' + CAST([DestinationStation] AS varchar(10)) + '
AND TRV.SourceStationID IS NULL'
FROM [Tickets].[dbo].[TCK_TMP_Fact_ALL_Travels_History_FromMissing]

A few comments I want to make before you read this answer:
I still believe this is an XY Problem and that we should really be answering the real problem you have; what ever that is (you haven't told us).
I have answered the question literally. This will be far from performant and it's still not got an order for the TOP.
This is untested due to a lack of sample data.
Anyway, you can do this with a CURSOR and a parametrised dynamic statement. I have guessed your data types, and as I have no sample data I cannot test to see if this is valid. If the dynamic statement errors, you'll have to trouble shoot that on your own, as I can't run it (obviously after fixing the data types in all locations).
I've also removed the 3 part naming and enforced a connection to the Tickets database prior to the batch.
USE Tickets;
GO
DECLARE #SQL nvarchar(MAX),
#CRLF nchar(2) = NCHAR(13) + NCHAR(10);
SET #SQL = N'UPDATE TOP (#Deploy) TRV' + #CRLF + --Don't forget, this translates to #Deploy Arbirtrary rows, not the "top" #Deploy rows, due to a lack of any ordering.
N'SET TRV.SourceStationID = #StationFrom,' + #CRLF +
N' TRV.MissingStationSourceCode = 888' + #CRLF +
N'FROM [dbo].TCK_STG_Fact_Contract_Magnetic_Travels1 TRV' + #CRLF +
N' LEFT OUTER JOIN [dbo].[TCK_DWH_Dim_Date] DAT ON CAST(TRV.[ExitDate] AS DATE) = CAST(DAT.Date AS DATE)' + #CRLF +
N' LEFT OUTER JOIN [dbo].[TCK_DWH_Dim_Manual_PartOfDay] POD ON DATEPART(HOUR,TRV.[ExitDate]) = POD.PartOfDay_Hour' + #CRLF +
N'WHERE DAT.Day_Type_Code = #DayTypeCode' + #CRLF +
N' AND POD.PartOfDay_Code = #PartOfDayCode' + #CRLF +
N' AND TRV.DestinationStation = #DestinationStation' + #CRLF +
N' AND TRV.SourceStationID IS NULL;';
DECLARE Missing_Cursor CURSOR FAST_FORWARD FOR
SELECT Deploy,
Station_From,
Day_Type_Code,
PartOfDay_Code,
DestinationStation
FROM [dbo].[TCK_TMP_Fact_ALL_Travels_History_FromMissing]
DECLARE #Deploy int, --Assumed data type, due to being used in TOP
#StationFrom int, --Guessed Datatype
#DayTypeCode int, --Guessed Datatype
#PartOfDayCode int, --Guessed Data Type
#DestinationStation varchar(10); --Guessed Data Type
OPEN Missing_Cursor;
FETCH NEXT FROM Missing_Cursor
INTO #Deploy, #StationFrom, #DayTypeCode, #PartOfDayCode, #DestinationStation;
WHILE ##FETCH_STATUS = 0 BEGIN
--Uses same assumed data types
EXEC sys.sp_executesql #SQL, N'#Deploy int, #StationFrom int, #DayTypeCode int, #PartOfDayCode int, #DestinationStation varchar(10)', #Deploy, #StationFrom, #DayTypeCode, #PartOfDayCode, #DestinationStation;
FETCH NEXT FROM Missing_Cursor
INTO #Deploy, #StationFrom, #DayTypeCode, #PartOfDayCode, #DestinationStation;
END
CLOSE Missing_Cursor;
DEALLOCATE Missing_Cursor;

suggestions here did it with the same time.
what solved the performance issues was adding 2 indexes
thx all for trying to help

Related

Trying to find views with and without rows

There are 226 views in our database, and we would like to find out which ones are empty. I have written the code below and the output says only that every view contains rows, when I know that is not true.
I started by using this code to find out if some of the views had rows:
select case when exists (select 1 from a_view)
then 'contains rows'
else 'doesnt contain rows'
This worked fine but I am trying to wrap this code inside a looping query that will give me this output for every view. The code below is as far as I have gotten and as I stated above, the output just says 'contains rows' for every view, which is not true.
declare #counter int
--- table variable for input
declare #tblname table(name_ varchar(400))
--- table variable for output
declare #outtbl table(name_ varchar(400))
--- the number of views present to end while loop
declare #viewNumber int = (select count(*) from sys.views)
--- inserting data into table variable
insert into #tblname
select name from sys.views
set #counter = 1
while exists (select name_ from #tblname) and #counter <= #viewNumber
begin
insert into #outtbl select case when exists (select 1 from #tblname)
then 'contains rows'
else 'doesnt contain rows'
end
set #counter = #counter + 1
end
select * from #outtbl
Here is a somewhat manual but relatively simple method:
select replace('
select ''[name]'' as view_name, (case when exists (select 1 from [name]) then ''contains rows'' else ''does not contain rows'' end)
',
'[name]', v.name)
from sys.views v;
You can run this in SSMS. Then just copy all the rows into a new query window and run the query. You can add union all between the queries so all are returned in a single result set.
Here is a db<>fiddle.
A different idea, but still using Dynamic SQL to get a count, is to create a bunch of INSERT statements to insert the counts into a temporary table, and finally retrieve that count:
DECLARE #SQL nvarchar(MAX);
SET #SQL = N'CREATE TABLE #ViewRows (Viewname sysname,' + NCHAR(13) + NCHAR(10) +
N' RowNum int);' + NCHAR(13) + NCHAR(10) +
STUFF((SELECT NCHAR(13) + NCHAR(10) +
N'INSERT INTO #ViewRows (ViewName, RowNum)'+ NCHAR(13) + NCHAR(10) +
N'SELECT N' + QUOTENAME(V.TABLE_SCHEMA + N'.' + v.TABLE_NAME,'''') + N', (SELECT COUNT(*) FROM ' + QUOTENAME(V.TABLE_SCHEMA) + N'.' + QUOTENAME(v.TABLE_NAME) + N');'
FROM INFORMATION_SCHEMA.VIEWS V
FOR XML PATH(''),TYPE).value('.','nvarchar(MAX)'),1,2,N'') + + NCHAR(13) + NCHAR(10) +
N'SELECT * FROM #ViewRows;';
SELECT #SQL;
EXEC sp_executesql #SQL;

SQL Using parameter in WHERE statement

Think I am missing something really obvious but I want to use a parameter in a where statement but when I do I get the following error (This is being run as a stored procedure if that makes any difference)
Invalid column name 'John'
The where statement in question
USE [Reports]
GO
/****** Object: StoredProcedure [Reports].[Alarm_TestSignOffFull_Qry] Script Date: 25/10/2018 08:56:26 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [Reports].[CustomerSearch]
-- Add the parameters for the stored procedure here
#Database VARCHAR(20)
,#Schema VARCHAR(20)
,#Name VARCHAR(20)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
EXEC ('
USE ' + #Database + '
SELECT Customer.Name,
[Product Categories].[Product Number]
RIGHT JOIN ((' + #Schema +'.Customer INNER JOIN ' + #Schema +'.Client ON Customer.Name = Client.Name)
LEFT JOIN ' + #Schema +'.Product ON Client.Name = Product.Client)
ON [Product Categories].[Product Number] = Client.Product
WHERE (Customer.Name = ' + #Name + ' AND Customer.Order = ''Y'') OR (Client.Name = ' + #Name + ' AND Customer.Order = ''Y'');
' )
END
GO
The parameter #Name is declared as VARCHAR(20)
Dont think too much about it had to find and replace table names and column names and stuff to make sure I am allowed to post it.
The select on the real thing also brings through a lot more fields but not too worried about that for this question
To emphasize it is the where statements that are going wrong the rest of the query works and it all works when I do not use any parameters
I'm posting this as answer, as the comments aren't enough to explain, however, there is far too little detail here to actually answer the OP's question.
Firstly, the error the OP is getting would be impossible to get with the tiny amount of SQL they have provided. If we expand it into a full Pseudo-SQL query, we get:
SELECT {Columns}
FROM Customer
WHERE Customer.Name = (' + #Name + ');
This would return rows in the Customer table, where Name has the literal string value ' + #Name + '. Very unlikely.
I suspect that the OP simply needs to do:
SELECT {Columns}
FROM Customer
WHERE Customer.Name = #Name;
HOWEVER, the error the OP is getting strong implies they are using Dynamic SQL. This means they have a query like this:
DECLARE #SQL nvarchar(MAX);
DECLARE #Name varchar(20) = 'John';
SET #SQL = N'SELECT {Columns} FROM Customer WHERE Customer.Name = (' + #Name + ');';
EXEC (#SQL);
The problem here is that translates into the SQL:
SELECT {Columns} FROM Customer WHERE Customer.Name = (John);
Notice, no quotes around John, and why the error.
What you are doing here, however, is a very bad idea. Raw string concatenation like that leaves your SQL wide open to injection(SQL injection). Parametrise your SQL:
DECLARE #SQL nvarchar(MAX);
DECLARE #Name varchar(20) = 'John';
SET #SQL = N'SELECT {Columns} FROM Customer WHERE Customer.Name = #dName;'
EXEC sp_executesql #SQL, N'#dName varchar(20)',#dName = #Name;`
Edit: Ok, the OP has provided us with their query. Honestly, it's a mess, far worse that I wanted it to be. Like i said before, raw string concatenation is an awful idea, it leaves you open to injection. You can't get rid of concatenation for dynamic objects, but you can use QUOTENAME, which makes the code safe(r).
You're also missing a FROM; no idea what that needs to be, so i've left that as pseudo-sql. That RIGHT JOIN is very messy too, but I've no idea what you're trying to achieve there.
Anyway, this need to replace your EXEC command. Read the below, understand the below, and don't make the mistake of concatenating raw strings in your dynamic SQL:
DECLARE #SQL nvarchar(MAX)
SET #SQL = N' USE ' + QUOTENAME(#Database) + N';' + NCHAR(10) +
N'SELECT Customer.Name,' + NCHAR(10) +
N' [Product Categories].[Product Number]' + NCHAR(10) +
--where is your FROM?
N'FROM {Something}' + NCHAR(10) + --This needs fixing
N' RIGHT JOIN((' + QUOTENAME(#Schema) + N'.Customer' + NCHAR(10) + --This whole thing is messy, but i'm not fixing it, as I have no data
N' INNER JOIN ' + QUOTENAME(#Schema) + N'.Client ON Customer.Name = Client.Name)' + NCHAR(10) +
N' LEFT JOIN ' + QUOTENAME(#Schema) + N'.Product ON Client.Name = Product.Client)ON [Product Categories].[Product Number] = Client.Product' + NCHAR(10) +
N'WHERE (Customer.Name = #dName' + NCHAR(10) +
N' AND Customer.[Order] = ''Y'')' + NCHAR(10) +
N' OR (Client.Name = #dName' + NCHAR(10) +
N' AND Customer.[Order] = ''Y'');';
EXEC sp_executesql #SQL, N'#dName varchar(20)', #dName = #Name;
If you are directly write in sql then you can use as below
WHERE Customer.Name = #Name
You are using a Dynamic SQL, and if you print your query it will be like
WHERE Customer.Name = (John)
And that's wrong, you can do like
EXECUTE sp_executesql N' ..WHERE Customer.Name = #CName',
N'#CName VARCHAR(20)',
#CName = 'John';
Or even
--#Name should be declared and has 'John' value
EXECUTE sp_executesql N' ..WHERE Customer.Name = #CName',
N'#Name VARCHAR(20)',
#Name = #Name;
Why does SQL think that the parameter is a column and not just plain text?
Well, as you can see before, the parameter you pass will be John not 'John', thus SQL Server will think it's a column name.
try giving single quotes in where clause
WHERE (Customer.Name = ''' + #Name + ''' AND Customer.Order = ''Y'')
OR (Client.Name = ''' + #Name + ''' AND Customer.Order = ''Y'');

Dynamic SQL Stored Procedure 2nd result set

I am working on a request to display selected test results from two tables via SSRS. I have developed the dynamic SQL to accomplish this but got stuck when running the stored procedure, as I only receive the first result set.
This stored procedure first queries a tag name table that is used to build columns for the second query... which retrieves the actual desired data. The SP returns the column names but does not return the needed second result set.
I realize this is an ugly solution but our IT group had no input into original database design, so now we're trying to do what we can to help.
Code:
DECLARE #cols as NVARCHAR(MAX), #query1 as NVARCHAR(MAX), #query2 as NVARCHAR(MAX),
#FLOATTABLE NVARCHAR(MAX), #TAGTABLE NVARCHAR(MAX),#startdate as NVARCHAR(MAX),
#ENDDATE AS NVARCHAR(MAX), #results as NVARCHAR(MAX)
set #FLOATTABLE = 'dbo.TRW_TESTER_FLOATTABLE' --for testing purposes only
set #tagtable = 'dbo.TRW_TESTER_TAGTABLE' --for testing purposes only
Set #startdate='2013-12-05' -- for testing purposes only
Set #enddate='2013-12-31' -- for tesying purposes only
set #query2 = 'SELECT STUFF((SELECT DISTINCT '','' +
QUOTENAME(CONVERT(VARCHAR,TagName),'
+ '''"'') FROM ' + #TAGTABLE + ' FOR XML PATH ('''')),1,1,'''')'
EXECUTE sp_executeSQL #query2, #Cols OUTPUT
Set #query1 = 'SELECT DISTINCT DateAndTime, Millitm, ' + #cols + ' FROM ( select
T.DateAndTime, T.Millitm, N.TagName, T.Val from ' + #FLOATTABLE + ' T LEFT JOIN ' +
#TAGTABLE + ' N ON T.TagIndex=N.TagIndex WHERE T.DateAndTime Between '''+ #startdate +
''' AND '''+ #enddate +''') x PIVOT (MAX(Val) for TagName IN (' + #cols + ')) p'
EXECUTE sp_executeSQL #query1, #results OUTPUT

Generating Scripts for Specific Records in SQL Server

This is probably a bit of a limited, but valuable scenario. I have a SQL Server 2008 database with a table that has millions of records. There appears to be an intermittent problem with several of the records. I'm trying to repro the problem. In an effort to do this, I finally got the ID of an offending record. I would like to generate an INSERT statement associated with this single record in my PROD database. Then I can easily migrate it into my TESTING database in an effort to repro and resolve the problem.
Basically, I need to generate a single INSERT statement for a single record from a single table where I know the primary key value of the record.
Does anyone have any ideas of how I can accomplish this? Essentially, I want to generate insert statements on a conditional basis.
Thank you!
First try to recreate what you want to insert with a SELECT statement.
After that you can insert into the table with a INSERT INTO like this:
INSERT INTO tablename
SELECT ....
If they are on different servers, you can use INSERT like this:
INSERT INTO tablename VALUES (...)
using the values given by the SELECT in the other server fill the values in the insert.
In your specific case I think you can do this:
CREATE PROCEDURE dbo.GenerateSingleInsert
#table NVARCHAR(511), -- expects schema.table notation
#pk_column SYSNAME, -- column that is primary key
#pk_value INT -- change data type accordingly
AS
BEGIN
SET NOCOUNT ON;
DECLARE #cols NVARCHAR(MAX), #vals NVARCHAR(MAX),
#valOut NVARCHAR(MAX), #valSQL NVARCHAR(MAX);
SELECT #cols = N'', #vals = N'';
SELECT #cols = #cols + ',' + QUOTENAME(name),
#vals = #vals + ' + ' + REPLICATE(CHAR(39),3) + ','
+ REPLICATE(CHAR(39),3) + ' + ' + REPLICATE(CHAR(39),2) + '+'
+ 'RTRIM(' + CASE WHEN system_type_id IN (40,41,42,43,58,61) THEN
'CONVERT(CHAR(8), ' + QUOTENAME(name) + ', 112) + '' ''
+ CONVERT(CHAR(14), ' + QUOTENAME(name) + ', 14)'
ELSE 'REPLACE(' + QUOTENAME(name) + ','''''''','''''''''''')' END + ')
+ ' + REPLICATE(CHAR(39),2)
FROM sys.columns WHERE [object_id] = OBJECT_ID(#table)
AND system_type_id <> 189 -- can't insert rowversion
AND is_computed = 0; -- can't insert computed columns
SELECT #cols = STUFF(#cols, 1, 1, ''),
#vals = REPLICATE(CHAR(39), 4) + ' + ' + STUFF(#vals, 1, 13, '')
+ REPLICATE(CHAR(39), 2);
SELECT #valSQL = N'SELECT #valOut = ' + #vals + ' FROM ' + #table + ' WHERE '
+ QUOTENAME(#pk_column) + ' = ''' + RTRIM(#pk_value) + ''';';
EXEC sp_executesql #valSQL, N'#valOut NVARCHAR(MAX) OUTPUT', #valOut OUTPUT;
SELECT SQL = 'INSERT ' + #table + '(' + #cols + ') SELECT ' + #valOut;
END
GO
So let's try it out:
CREATE TABLE dbo.splunge
(
ID INT, dt DATETIME, rv ROWVERSION, t NVARCHAR(MAX)
);
INSERT dbo.splunge(ID, dt, t)
SELECT 1, GETDATE(), 'foo'
UNION ALL SELECT 2, GETDATE(), 'bar'
UNION ALL SELECT 3, GETDATE(), 'O''Brien';
EXEC dbo.GenerateSingleInsert N'dbo.splunge', N'ID', 1;
SQL
-------------
INSERT dbo.splunge([ID],[dt],[t]) SELECT '1','20120517 10:07:07:330','foo'
EXEC dbo.GenerateSingleInsert N'dbo.splunge', N'ID', 2;
SQL
-------------
INSERT dbo.splunge([ID],[dt],[t]) SELECT '2','20120517 10:07:07:330','bar'
EXEC dbo.GenerateSingleInsert N'dbo.splunge', N'ID', 3;
SQL
-------------
INSERT dbo.splunge([ID],[dt],[t]) SELECT '3','20120517 10:07:07:330','O''Brien'
If there is an IDENTITY column you may need to set SET IDENTITY_INSERT ON for the TEST table, and verify that there is no collision. Probably about 500 caveats I should mention, I haven't tested all data types, etc.
However in the more general case there is a lot more to it than this. Vyas K has a pretty robust stored procedure that should demonstrate how complicated it can get:
http://vyaskn.tripod.com/code/generate_inserts_2005.txt
You are probably far better off using a tool like Red-Gate's SQL Data Compare to pick a specific row and generate an insert for you. As I've blogged about, paying for a tool is not just about the money, it's about the hours of troubleshooting and bug-fixing that someone else has already done for you.
Aaron,
I liked your code, it solved a problem for me. I ran into a few issues using it (like you said I would) with nulls and the text type so I made some changes to address those issues.
ALTER PROCEDURE dbo.GenerateSingleInsert
#table NVARCHAR(511), -- expects schema.table notation
#pk_column SYSNAME, -- column that is primary key
#pk_value INT -- change data type accordingly
AS
BEGIN
SET NOCOUNT ON;
DECLARE #cols NVARCHAR(MAX), #vals NVARCHAR(MAX),
#valOut NVARCHAR(MAX), #valSQL NVARCHAR(MAX);
SELECT #cols = N'', #vals = N'';
SELECT #cols = #cols + ',' + QUOTENAME(name),
#vals = #vals + ' + '','' + ' + 'ISNULL('+REPLICATE(CHAR(39),4)+'+RTRIM(' +
CASE WHEN system_type_id IN (40,41,42,43,58,61) -- datetime types
THEN
'CONVERT(CHAR(8), ' + QUOTENAME(name) + ', 112) + '' ''+ CONVERT(CHAR(14), ' + QUOTENAME(name) + ', 14)'
WHEN system_type_id IN (35) -- text type NOTE: can overflow
THEN
'REPLACE(CAST(' + QUOTENAME(name) + 'as nvarchar(MAX)),'+REPLICATE(CHAR(39),4)+','+REPLICATE(CHAR(39),6)+')'
ELSE
'REPLACE(' + QUOTENAME(name) + ','+REPLICATE(CHAR(39),4)+','+REPLICATE(CHAR(39),6)+')'
END
+ ')+' + REPLICATE(CHAR(39),4) + ',''null'') + '
FROM sys.columns WHERE [object_id] = OBJECT_ID(#table)
AND system_type_id <> 189 -- can't insert rowversion
AND is_computed = 0; -- can't insert computed columns
SELECT #cols = STUFF(#cols, 1, 1, ''),
#vals = REPLICATE(CHAR(39),2) + STUFF(#vals, 1, 6, '') + REPLICATE(CHAR(39),2) ;
SELECT #valSQL = N'SELECT #valOut = ' + #vals + ' FROM ' + #table + ' WHERE '
+ QUOTENAME(#pk_column) + ' = ''' + RTRIM(#pk_value) + ''';';
EXEC sp_executesql #valSQL, N'#valOut NVARCHAR(MAX) OUTPUT', #valOut OUTPUT;
SELECT SQL = 'INSERT ' + #table + '(' + #cols + ') SELECT ' + #valOut;
END

Executing dynamic SQL in a SQLServer 2005 function

I will preface this question by saying, I do not think it is solvable. I also have a workaround, I can create a stored procedure with an OUTPUT to accomplish this, it is just easier to code the sections where I need this checksum using a function.
This code will not work because of the Exec SP_ExecuteSQL #SQL calls. Anyone know how to execute dynamic SQL in a function? (and once again, I do not think it is possible. If it is though, I'd love to know how to get around it!)
Create Function Get_Checksum
(
#DatabaseName varchar(100),
#TableName varchar(100)
)
RETURNS FLOAT
AS
BEGIN
Declare #SQL nvarchar(4000)
Declare #ColumnName varchar(100)
Declare #i int
Declare #Checksum float
Declare #intColumns table (idRecord int identity(1,1), ColumnName varchar(255))
Declare #CS table (MyCheckSum bigint)
Set #SQL =
'Insert Into #IntColumns(ColumnName)' + Char(13) +
'Select Column_Name' + Char(13) +
'From ' + #DatabaseName + '.Information_Schema.Columns (NOLOCK)' + Char(13) +
'Where Table_Name = ''' + #TableName + '''' + Char(13) +
' and Data_Type = ''int'''
-- print #SQL
exec sp_executeSql #SQL
Set #SQL =
'Insert Into #CS(MyChecksum)' + Char(13) +
'Select '
Set #i = 1
While Exists(
Select 1
From #IntColumns
Where IdRecord = #i)
begin
Select #ColumnName = ColumnName
From #IntColumns
Where IdRecord = #i
Set #SQL = #SQL + Char(13) +
CASE WHEN #i = 1 THEN
' Sum(Cast(IsNull(' + #ColumnName + ',0) as bigint))'
ELSE
' + Sum(Cast(IsNull(' + #ColumnName + ',0) as bigint))'
END
Set #i = #i + 1
end
Set #SQL = #SQL + Char(13) +
'From ' + #DatabaseName + '..' + #TableName + ' (NOLOCK)'
-- print #SQL
exec sp_executeSql #SQL
Set #Checksum = (Select Top 1 MyChecksum From #CS)
Return isnull(#Checksum,0)
END
GO
It "ordinarily" can't be done as SQL Server treats functions as deterministic, which means that for a given set of inputs, it should always return the same outputs. A stored procedure or dynamic sql can be non-deterministic because it can change external state, such as a table, which is relied on.
Given that in SQL server functions are always deterministic, it would be a bad idea from a future maintenance perspective to attempt to circumvent this as it could cause fairly major confusion for anyone who has to support the code in future.
Here is the solution
Solution 1:
Return the dynamic string from Function then
Declare #SQLStr varchar(max)
DECLARE #tmptable table (<columns>)
set #SQLStr=dbo.function(<parameters>)
insert into #tmptable
Exec (#SQLStr)
select * from #tmptable
Solution 2:
call nested functions by passing parameters.
You can get around this by calling an extended stored procedure, with all the attendant hassle and security problems.
http://decipherinfosys.wordpress.com/2008/07/16/udf-limitations-in-sql-server/
http://decipherinfosys.wordpress.com/2007/02/27/using-getdate-in-a-udf/
Because functions have to play nicely with the query optimiser there are quite a few restrictions on them. This link refers to an article that discusses the limitations of UDF's in depth.
Thank you all for the replies.
Ron: FYI, Using that will throw an error.
I agree that not doing what I originally intended is the best solution, I decided to go a different route. My two choices were to use sum(cast(BINARY_CHECKSUM(*) as float)) or an output parameter in a stored procedure. After unit testing speed of each, I decided to go with sum(cast(BINARY_CHECKSUM(*) as float)) to get a comparable checksum value for each table's data.