I am trying to create a stored procedure that selects from a database name that would be parameterized. However, I am having a lot of trouble doing so. I am trying to perform something as simple as the following:
DECLARE #tableName VARCHAR
SET #tableName = 'MY_TABLE_NAME'
SELECT
*
FROM
#tableName
This produces the error: Incorrect syntax near '#tableName'.
Could someone please tell me how I could select from a parameterized table name?
Execute dynamic SQL in this case.
DECLARE #tableName VARCHAR
SET #tableName = 'MY_TABLE_NAME'
exec('
SELECT
*
FROM ' + #tableName )
Related
How can i avoid using dynamic from clause? Even if i don't know the database name, i prefer to use a static statement, like this:
select *
into #tempTable
from #DBName.Invoices
where InvoiceId = 5.
I got this error: Msg 102, Level 15, State 1, Line 6
Incorrect syntax near '.'.
I need to use select into clause because the column names may be different from each databases;
Thanks!
Unfortunately you will have to use dynamic SQL for this, see below for an example
Declare #DBNAME NVARCHAR(MAX) = 'xxx'
Declare #SQL NVARCHAR(MAX) ='select *
into #tempTable
from ' + #DBName + '.Invoices
where InvoiceId = 5.'
execute sp_executesql #SQL
How can i avoid using dynamic from clause? Even if i don't know the database name, i prefer to use a static statement
SQL wont accept columnnames,tablenames,databasenames as parameters.so unless you you avoid them,you cant avoid dynamic sql..
Change your query to dynamic sql to avoid error..But again you will have a problem with temp tables scope
--This will fail ,because temp table falls under different scope
Declare #sql nvarchar(4000)
set #sql='
select *
into #tempTable
from #DBName.Invoices
where InvoiceId = 5'
---one option is to use global temp tables
declare #dbname varchar(1000)
set #dbname=db_name()
declare #sql nvarchar(4000)
set #sql='select *
into ##tempTable
from '+#DBName+'.dbo.test_Delete '
exec(#sql)
select * from ##temptable
But be carefull with above approach,since above temp table have global scope..
You also can use Openrowset ,some thing like below
select * into #temp from openrowset
('SQLNCLI','Server=yourinstancename;Trusted_Connection=yes;', 'select * form table')
Is there a way to use a variable to name a column in SQL query results? My example below gives an "Incorrect syntax" error?
declare #ColumnName varchar(100) = 'Column 1'
Select CustomerNumber as #ColumnName
from Customers
Generally, SQL isn't going to handle defining variables to use as column aliases. This means you'll likely have to resort to using dynamic SQL, which involves building your query and then executing it manually via the sp_executesql procedure.
The following is an example of your existing query executed dynamically using SQL Server :
-- Define your variable
DECLARE #ColumnName VARCHAR(100) = 'Column 1'
-- Define your SQL query
DECLARE #SQL NVARCHAR(200) = 'SELECT CustomerNumber AS ' + #ColumnName + ' FROM Customers'
-- Execute your query dynamically
EXEC sp_executesql #SQL
I have a database with the name "Union". I am trying execute SQL for this database in the MAINT table but since 'union' is a SQL command it is throwing errors. I can get the query to run when executing from Union database. Would dynamic SQL be able to fix my problem or should I change the database name?
I keep getting incorrect syntax near keyword 'UNION' here is what I have so far,
DECLARE #sql varchar(max)
DECLARE #Database varchar(5)
Set #Database = 'UNION'
SELECT #sql = 'SELECT '+#Database+' as ''Database'', '+#Database+'.hsi.useraccount.username as ''User Name'',
'+#Database+'.hsi.useraccount.realname as ''Real Name''
FROM '+#Database+'.hsi.useraccount
WHERE '+#Database+'.hsi.useraccount.username NOT LIKE ''%deactivated%'' and '+#Database+'.hsi.useraccount.username not like ''%administrator'' and '+#Database+'.hsi.useraccount.username not like ''%internal%'''
execute(#sql)
Add [] brackets around Schema names.
SELECT #sql = REPLACE('SELECT [#Database] as ''Database'', [#Database].hsi.useraccount.username as ''User Name'',
[#Database].hsi.useraccount.realname as ''Real Name''
FROM [#Database].hsi.useraccount
WHERE [#Database].hsi.useraccount.username NOT LIKE ''%deactivated%'' and [#Database].hsi.useraccount.username not like ''%administrator'' and [#Database].hsi.useraccount.username not like ''%internal%'''
,'#Database',#Database)
As long as the text "#Database" text doesn't appear anywhere else in your select statement, just throw it into a REPLACE() function and avoid all that embedded quote syntax and string concatenation headache.
You also can use quotename instead of manually entering square brackets
declare #db nvarchar(100)
set #db='performance'
declare #sql nvarchar(max)
set #sql='select * from '+QUOTENAME(#db)+'.'+quotename('dbo')+'.'+QUOTENAME('orders')
print #sql
exec(#sql)
I am trying to store the results of an SQL query into a variable.The query simply detects the datatype of a column, hence the returned result is a single varchar.
SET #SQL =
'declare ##x varchar(max) SET ##x = (select DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS
WHERE Table_name = ' +char(39)+#TabName+char(39) +
' AND column_name = ' +char(39)+#colName+char(39) + ')'
EXECUTE (#SQL)
Anything within the 'SET declaration' cannot access any variables outside of it and vice versa, so I am stuck on how to store the results of this query in a varchar variable to be accessed by other parts of the stored procedure.
You dont need a dynamic query to achieve what you want, below query will give the same result as yours.
declare #x varchar(max)
declare #tableName varchar(100), #ColumnName varchar(50)
set #tableName = 'Employee'
set #ColumnName = 'ID'
select #x = DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS
where
Table_Name = #tableName
and column_name = #ColumnName
select #x
All user-defined variables in T-SQL have private local-scope only. They cannot be seen by any other execution context, not even nested ones (unlike #temp tables, which can be seen by nested scopes). Using "##" to try to trick it into making a global-variable doesn't work.
If you want to execute dynamic SQL and return information there are several ways to do it:
Use sp_ExecuteSQL and make one of the parameters an OUTPUT parameter (recommended for single values).
Make a #Temp table before calling the dynamic SQL and then have the Dynamic SQL write to the same #Temp table (recommended for multiple values/rows).
Use the INSERT..EXEC statement to execute your dynamic SQL which returns its information as the output of a SELECT statement. If the INSERT table has the same format as the dynamic SQL's SELECT output, then the data output will be inserted into your table.
If you want to return only an integer value, you can do this through the RETURN statement in dynamic SQL, and receive it via #val = EXEC('...').
Use the Session context-info buffer (not recommended).
However, as others have pointed out, you shouldn't actually need dynamic SQL for what you are showing us here. You can do just this with:
SET #x = ( SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS
WHERE Table_name = #TabName
AND column_name = #colName )
You may want to consider using the sp_executesql stored procedure for dynamic sql.
The following link provides a good usage example of sp_executesql procedure with output parameters:
http://support.microsoft.com/kb/262499
I want to create a SQL tabled-value function that will receive a query as n parameter through my API. In my function I want execute that query. The query will be a SELECT statement.
This is what I have done so far and what to achieve but it is not the correct way to do so.
CREATE FUNCTION CUSTOM_EXPORT_RESULTS (
#query varchar(max),
#guid uniqueidentifier,
#tableName varchar(200))
RETURNS TABLE
AS
RETURN
(
-- Execute query into a table
SELECT *
INTO #tableName
FROM (
EXEC(#query)
)
)
GO
Please suggest the correct way!
Try this one -
CREATE PROCEDURE dbo.sp_CUSTOM_EXPORT_RESULTS
#query NVARCHAR(MAX) = 'SELECT * FROM dbo.test'
, #guid UNIQUEIDENTIFIER
, #tableName VARCHAR(200) = 'test2'
AS BEGIN
SELECT #query =
REPLACE(#query,
'FROM',
'INTO [' + #tableName + '] FROM')
DECLARE #SQL NVARCHAR(MAX)
SELECT #SQL = '
IF OBJECT_ID (N''' + #tableName + ''') IS NOT NULL
DROP TABLE [' + #tableName + ']
' + #query
PRINT #SQL
EXEC sys.sp_executesql #SQL
RETURN 0
END
GO
Output -
IF OBJECT_ID (N'test2') IS NOT NULL
DROP TABLE [test2]
SELECT * INTO [test2] FROM dbo.test
What I see in your question is encapsulation of:
taking a dynamic SQL expression
executing it to fill a parametrized table
Why do you want to have such an encapsulation?
First, this can have a negative impact on your database performance. Please read this on EXEC() and sp_executesql() . I hope your SP won't be called from multiple parts of your application, because this WILL get you into trouble, at least performance-wise.
Another thing is - how and where are you constructing your SQL? Obviously you do it somewhere else and it seems its manually created. If we're talking about a contemporary application, there are lot of OR/M solutions for this and manual construction of TSQL in runtime should be always avoided if possible. Not to mention EXEC is not guarding you against any form of SQL injection attacks. However, if all of this is a part of some database administration TSQL bundle, forget his paragraph.
At the end, if you want to simply load a new table from some existing table (or part of it) as a part of some administration task in TSQL, consider issuing a SELECT ... INTO ... This will create a new target table structure for you (omitting indexes and constraints) and copy the data. SELECT INTO will outperform INSERT INTO SELECT because SELECT INTO gets minimally logged.
I hope this will get you (and others) at least a bit on the right track.
You can use stored procedure as well, here is the code that you can try.
CREATE FUNCTION CUSTOM_EXPORT_RESULTS
(
#query varchar(max),
#guid uniqueidentifier,
#tableName varchar(200)
)
RETURNS TABLE
AS
RETURN
(
declare #strQuery nvarchar(max)
-- Execute query into a table
SET #strQuery = REPLACE(#query,'FROM', 'INTO '+#tableName+' FROM')
exec sp_executesql #strQuery
)
GO