I have the following code:
UPDATE myTable
SET Col1 = #Value
However, I have a table that has over a 100 columns and want to be able to specify a column name by passing the name into the query similar to:
UPDATE myTable
SET #ColName = #Value
When I do this I get an error. Is there a good solution to this? Its probably something simple!
Thank you in advanced.
You'll have to use dynamic SQL, and write it to make sure you don't let Little Bobby Tables in. Something like this:
DECLARE #sql NVARCHAR(500)
SET #sql = N'UPDATE myTable SET ' + QUOTENAME(#colName) + ' = #pUpdateVal'
EXEC sp_ExecuteSQL #sql, '#pUpdateVal NVARCHAR(20)', #value
Make sure you change the type of #pUpdateVal to something appropriate for your environment, but this will mitigate the risk of injection attacks.
You'd have to revert to dynamic SQL to do this.
Agreed with the others, you'll need dynamic SQL for this; you can't define object names at run time in native SQL. For a full discussion on dynamic SQL see http://www.sommarskog.se/dynamic_sql.html
Related
I have this query in SQL Server:
select column
from table_53;
Now, I want to get this 53 from another table, so what I want to do is something like this:
select column
from table_(select id from table2);
Is there any way to do this in SQL Server?
This is definitely not the way SQL thinks and works. Maybe your suggested approach can be mimicked by way of writing stored procedures in which you create SQL-statements which are then evaluated. However, this will not be very efficient.
A better approach would be to store the values of all your individual separate tables into one master table and mark them in a separate column tblid with their number (e.g. 53). Then you can always filter them from this master table by looking for this tblid.
You need dynamic sql query here.
declare #sqlQuery = 'select column
from table_(';
set #sqlQuery = #sqlQuery + 'select id from table2)';
EXEC (#sqlQuery)
Note :- One of cons of using dynamic sql query is sql injection. I would suggest to have better table structure or try to used parameterized query.
Yes, you can, but using something like this:
DECLARE #ID INT;
DECLARE #QUERY NVARCHAR(MAX);
SELECT #ID = ID FROM TABLE_2;
--IF #ID EQUALS 53 THEN
SET #QUERY = 'SELECT COLUMN FROM TABLE_' + CAST(#ID AS NVARCHAR(10));
-- #QUERY EQUALS TO 'SELECT COLUMN FROM TABLE_53'
EXEC (#QUERY);
I'm using this method (How to use a variable for the database name in T-SQL?) to pass a DBname into a variable. This variable is then used with something like this (simplified):
Select column From #DBname
However, when executed...You get, Command(s) completed successfully
Is there a way to adapt this method so that you can see the results of a query? (Not just create or alter a DB)
Something like this should work for you.
[[put code here that sets up #DBname]]
DECLARE #stmt NVARCHAR(MAX) = 'SELECT column FROM ' + #DBname;
EXEC sp_ExecuteSQL #stmt;
Edit: Note that I'm assuming you're using SQL server (you didn't specify in the question).
I'm wondering if it is possible to create a variable name when copying a table to another.
Here's my sort-of algorithm/code
DECLARE #NewTableName VARCHAR(50)
SET #NewTableName = 'MyTable_'+GETDATE() --MyTable_12282010 (for example)
SELECT *
INTO #NewTableName
FROM MyTable
I'm wondering if this is possible. I tried it before, but it failed. Any suggestions guys?
It is possible, but only using dynamic TSQL.
See sp_executesql (or the 2000 version sp_executesql)
Be aware of The Curse and Blessings of Dynamic SQL
I'm currently using sp_executesql to execute a T-SQL statement with a dynamic table name. However, it is really ugly to see something like:
set #sql = 'UPDATE '+Table_Name+' SET ... WHERE '+someVar+' = ... AND '+someVar2' = ...'
sp_executesql #sql
What I would rather like to have is a TABLE variable of which is a reference to a table, so I could do for example:
UPDATE TableRef SET ... WHERE ...
Because when I have really long T-SQL statements it gets really hard to read due to the format of it within a string.
Any suggestions would be helpful.
Why don't you pass the parameters to sp_executeSQL instead?
http://msdn.microsoft.com/en-us/library/ms188001.aspx
I'd also have a read of this article too http://www.sommarskog.se/dynamic_sql.html
You can't. If you want to use a dynamic table name in your SQL, you have to concatenate it into your string.
If you have a lot of references to the table name within your query, you can shorten it by aliasing the table name, and for all other instances, use the alias.
e.g.
SET #SQL = 'UPDATE t SET.... FROM ' + #TableName + ' t WHERE ....'
Just be very very careful when using dynamic SQL like this. Make sure you guard yourself against SQL injection.
I am trying to write a database script (SQL Server 2008) which will copy information from database tables on one server to corresponding tables in another database on a different server.
I have read that the correct way to do this is to use a sql statement in a format similar to the following:
INSERT INTO <linked_server>.<database>.<owner>.<table_name> SELECT * FROM <linked_server>.<database>.<owner>.<table_name>
As there will be several tables being copied, I would like to declare variables at the top of the script to allow the user to specify the names of each server and database that are to be used. These could then be used throughout the script. However, I am not sure how to use the variable values in the actual SQL statements. What I want to achieve is something like the following:
DECLARE #SERVER_FROM AS NVARCHAR(50) = 'ServerFrom'
DECLARE #DATABASE_FROM AS NVARCHAR(50) = 'DatabaseTo'
DECLARE #SERVER_TO AS NVARCHAR(50) = 'ServerTo'
DECLARE #DATABASE_TO AS NVARCHAR(50) = 'DatabaseTo'
INSERT INTO #SERVER_TO.#DATABASE_TO.dbo.TableName SELECT * FROM #SERVER_FROM.#DATABASE_FROM.dbo.TableName
...
How should I use the # variables in this code in order for it to work correctly?
Additionally, do you think my method above is correct for what I am trying to achieve and should I be using NVARCHAR(50) as my variable type or something else?
Thanks
There is probably a better way to do this, but what you are probably trying to do in your example is what's called dynamic SQL where you treat the statement as a string and the execute it. This would be section #2 here:
http://www.mssqltips.com/tip.asp?tip=1160
There are some major downsides to dynamic SQL. You see a couple other approaches that might be better in that article.
If you want to execute a dynamically generated query then you have to use sp_ExecuteSQL
HTH
For the nvarchar(50) - you'd be better using sysname. This is a synonym in SQL Server (for nvarchar(128)) and represents the maximum length of an object identifier.
have a look at http://msdn.microsoft.com/en-us/library/ms188001.aspx - sp_executesql takes a parameter that is a string and executes the sql in that string. so you'd need to concatenate #SERVER_FROM and other params with the INSERT INTO part to make the entire sql statement, and then pass to sp_executesql.
nvarchar(50) is fine, unless your server/database names are longer than that :)
You can create the select statement by concatenating all the information together and then use sp_executesql
so:
sp_executesql 'INSERT INTO ' + #SERVER_TO + '.' + #DATABASE_TO +
'.dbo.TableName SELECT * FROM ' + #SERVER_FROM + '.' +
#DATABASE_FROM+'.dbo.TableName'
I like to make templates for dynamic SQL things like this - it's a lot easier to maintain complex statements and also sometimes easier to handle nested quotes - and definitely easier when terms need to be repeated in multiple places (like column lists):
DECLARE #sql AS nvarchar(max);
SET #sql = 'INSERT INTO {#SERVER_TO}.{#DATABASE_TO}.dbo.TableName
SELECT *
FROM {#SERVER_FROM}.{#DATABASE_FROM}.dbo.TableName'
SET #sql = REPLACE(#sql, '{#SERVER_TO}', QUOTENAME(#SERVER_TO))
SET #sql = REPLACE(#sql, '{#DATABASE_TO}', QUOTENAME(#DATABASE_TO))
SET #sql = REPLACE(#sql, '{#SERVER_FROM}', QUOTENAME(#SERVER_FROM))
SET #sql = REPLACE(#sql, '{#DATABASE_FROM}', QUOTENAME(#DATABASE_FROM))
EXEC(#sql)