How to execute SQL statements saved in a table with T-SQL
You can use
EXECUTE sp_executesql @Query
to run your T-SQL
Here's a link to the MS docn for SQL Server 2005
http://msdn.microsoft.com/en-us/library/ms188001%28v=sql.90%29.aspx
SQL - execute query from table cells
This should help you go through all scripts in that table. With what you are doing, only one script will be run so if the table has 100 Scripts, only one will be executed. Hope this helps
DECLARE @Queries TABLE (ID INT IDENTITY(1,1),SQLScript VARCHAR(MAX))
DECLARE @STR_QUERY VARCHAR(MAX);
DECLARE @StartLoop INT
DECLARE @EndLoop INT
INSERT INTO @Queries
SELECT Query
FROM [AccHelper].[dbo].[Queries]
SELECT @EndLoop = MAX(ID), @StartLoop = MIN(ID)
FROM @Queries
WHILE @StartLoop < = @EndLoop
BEGIN
SELECT @STR_QUERY = SQLScript
FROM @Queries
WHERE ID = @StartLoop
EXEC (@STR_QUERY)
SET @StartLoop = @StartLoop + 1
END
Execute A Dynamic SQL statement Stored in a Column of a table
Had to look up what `lakh' was :)
As other comments mentioned this is not most optimal approach to DML, please consider refactoring. As it is you can combine your dynamic SQL in batches, e.g.:
DECLARE @sSQL nvarchar(max)
SET @sSQL = 'BEGIN TRAN; '
SELECT @sSQL = @sSQL + COLUMN_WITH_INSERT_STATEMENT + '; '
FROM TABLE
WHERE [limit number of rows]
SET @sSQL = @sSQL + 'COMMIT TRAN '
EXEC(@sSQL)
This way you can combine controlled number of INSERT statements into a single transaction. You can control number of inserts by means of WHERE statement (e.g. WHERE ID BETWEEN 1 and 100
to execute 100 INSERTs at a time) You can loop thru this condition (yes loop, but it it will not be looping thru individual rows, but thru conditions instead e.g.1 - 100, 101 - 200, 201 - 300 etc).
execute SQL query stored in a table
This seems a very peculiar requirement, and one which will be difficult to solve in a robust fashion. STMT_OR_VALUE is the embodiment of the One Column Two Usages anti-pattern. Furthermore, resolving STMT_OR_VALUE requires flow control logic and the use of dynamic SQL. Consequently it cannot be a pure SQL solution: you need to use PL/SQL to assemble and execute the dynamic query.
Here is a proof of concept for a solution. I have opted for a function which you can call from SQL. It depends on one assumption: every query string you insert into TEST1.STMT_OR_VALUE has a projection of a single numeric column and every value string is a CSV of numeric data only. With this proviso it is simple to construct a function which either executes a dynamic query or tokenizes the string into a series of numbers; both of which are bulk collected into a nested table:
create or replace function get_ids (p_name in test1.name%type)
return sys.odcinumberlist
is
l_rec test1%rowtype;
return_value sys.odcinumberlist;
begin
select * into l_rec
from test1
where name = p_name;
if l_rec.type = 'SQL_QUERY' then
-- execute a query
execute immediate l_rec.stmt_or_value
bulk collect into return_value;
else
-- tokenize a string
select xmltab.tkn
bulk collect into return_value
from ( select l_rec.stmt_or_value from dual) t
, xmltable( 'for $text in ora:tokenize($in, ",") return $text'
passing stmt_or_value as "in"
columns tkn number path '.'
) xmltab;
end if;
return return_value;
end;
/
Note there is more than one way of executing a dynamic SQL statement and a multiplicity of ways to tokenize a CSV into a series of numbers. My decisions are arbitrary: feel free to substitute your preferred methods here.
This function can be invoked with a table()
call:
select *
from data
where id in ( select * from table(get_ids('first'))) -- execute query
or id in ( select * from table(get_ids('second'))) -- get string of values
/
The big benefit of this approach is it encapsulates the logic around the evaluation of STMT_OR_VALUE and hides use of Dynamic SQL. Consequently it is easy to employ it in any SQL statement whilst retaining readability, or to add further mechanisms for generating a set of IDs.
However, this solution is brittle. It will only work if the values in the test1
table obey the rules. That is, not only must they be convertible to a stream of single numbers but the SQL statements must be valid and executable by EXECUTE IMMEDIATE. For instance, the trailing semi-colon in the question's sample data is invalid and would cause EXECUTE IMMEDIATE to hurl. Dynamic SQL is hard not least because it converts compilation errors into runtime errors.
Execute dynamic select query stored in a table
It's very poor practice storing SQL code in a table. Have you looked at views, stored procedures or inline table-valued functions?
Anyway, to execute the stored SQL in a table you would do something like this....
DECLARE @Sql NVARCHAR(MAX);
SELECT TOP 1 @Sql = RuleSql
FROM TableName --<-- table where sql is stored
WHERE <Some Condition>
Exec sp_executesql @Sql
Just saw your edit. To execute all the queries at once you would use a cursor something like.....
DECLARE @Sql NVARCHAR(MAX);
DECLARE Cur CURSOR LOCAL FAST_FORWARD FOR
SELECT RuleSql
FROM TableName --<-- table where sql is stored
OPEN Cur
FETCH NEXT FROM Cur INTO @Sql
WHILE (@@FETCH_STATUS = 0)
BEGIN
Exec sp_executesql @Sql
FETCH NEXT FROM Cur INTO @Sql
END
CLOSE Cur
DEALLOCATE Cur;
Executing T-SQL query from table
The actual reason for this error is the difference between EXEC @Test
(to execute a stored procedure or function) and EXEC (@Test)
(to execute a dynamic statement). Note, that you may use sp_executesql
to execute a dynamically generated statement:
CREATE PROCEDURE MergeTable @TableName VARCHAR(256)
AS
BEGIN
DECLARE @Test VARCHAR(max)
SELECT @Test = Query
FROM dbo.QueryMergeDWH
WHERE SourceTableName = @TableName
EXEC (@Test)
-- Or using sp_executesql
-- DECLARE @err int
-- EXEC @err = sp_executesql @Test
-- IF @err <> 0 PRINT 'Error'
END
GO
EXEC MergeTable @TableName = 'SGPREINVOICE'
Execute saved queries in table SQL Server
Use cursor over your table and execute as dynamic t-sql adding insert into
at the beginning of every value with SQL statement.
CREATE TABLE tSELECT
(
query VARCHAR(1000)
);
INSERT INTO tselect VALUES ('Select Max(acc),Min(acc) from my_table1')
CREATE TABLE result (min INT, max int);
BEGIN
DECLARE @stmt VARCHAR(1000);
DECLARE db_cursor CURSOR FOR SELECT * FROM tselect;
OPEN db_cursor FETCH NEXT FROM db_cursor INTO @stmt
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC('insert into result ' + @stmt);
FETCH NEXT FROM db_cursor INTO @stmt
END
CLOSE db_cursor
DEALLOCATE db_cursor
END;
Execute SQL Statement stored in table column
SET v_SQL=
'SET ?=(
SELECT
DATA_SQL
FROM TB_SQL
WHERE TBNAME='''||v_TBNAME||'''
)
';
PREPARE SQL_QUERY FROM v_SQL;
EXECUTE SQL_QUERY INTO v_INSERT_STATEMENT;
PREPARE SQL_INSERT FROM v_INSERT_STATEMENT;
EXECUTE SQL_INSERT;
Related Topics
Postgres Recursive Query with Row_To_JSON
How to Get a List of All Current Temporary Tables in SQL Server
How to Get Current Datetime in SQL
How to Solve Ora-00911: Invalid Character Error
How to Document Your Database Structure
Oracle Select for Update Behaviour
Using SQL Localdb in a Windows Service
Retrieve Id of Record Just Inserted into a Java Db (Derby) Database
Date/Timestamp to Record When a Record Was Added to the Table
SQL Searching Multiple Words in a String
Rails Virtual Attribute Search or SQL Combined Column Search
Executing a Dynamic SQL Statement into a Sys_Refcursor
Django Orm - Get Latest Record for Group