I having a problem with my current situation, I searched through any solution on the net but still I can't get it.
Here the question:
I have a bunch of SQL statements that need to be executed in a stored procedure by using cursor inside, each of the statements is performing an insert by selecting from a different database as well as table.
For example:
INSERT INTO Database1.Table1(column1, column2, column3)
SELECT column1,column2, column3
FROM Database2.Table2
WHERE --Some Condition
and maybe another executed SQL statement is like this
INSERT INTO Database1.Table3(column1, column2, column3, column4)
SELECT column1, column2, column3, column4
FROM Database3.Table3
WHERE --Some Condition
Okay, basically my process is like this
Execute Sql to insert into temp Tables --> Insert into a permanent Table from Temp Tables
From above two SQL statements, my executed result from database2 or 3 or may be 4,5 and etc. I will goes to my database1 for permanent store. In more summary way of telling that's is, I just want to made another copy of data that get from different source of database and store into my local database to do some further processing.
My main problem is my person in charge (or manager) told me to trow all executed result into a TEMP table or #Table before execute into the permanent.
Something like this:
INSERT INTO #Table3(column1, column2, column3, column4)
SELECT column1, column2, column3, column4
FROM Database3.Table3
WHERE --Some Condition
I went through some research on #Temp tables and I found it most of them is creating with 'FIX' column such as
CREATE TABLE #Table
(
column1 VARCHAR(10),
column2 VARCHAR(10),
column3 VARCHAR(10)
)
PROBLEM: is there anyway to create it with dynamic columns? More detail way of asking, is there anyway to insert by select into a #Temp table without prefix the column? Because that is impossible for me to create a bunch of temp table for each of executed SQL.
Thank you
PS 1: I am quite a newbie to SQL Server, please don't hesitate to voice out my mistake or error. We all learn from mistakes.
PS 2: Sorry for my poor English level, I tried my best to elaborate it more clearly.
Regards:
LiangCk
You say that you want something like
INSERT INTO #Table3(coloum1,coloum2,coloum3,coloum4)
Select coloum1,coloum2,coloum3,coloum4
FROM Database3.Table3
WHERE --Some Condition
without having to create the temp table with fixed columns first.
This would work:
Select coloum1,coloum2,coloum3,coloum4
INTO #Table3
FROM Database3.Table3
WHERE --Some Condition
You don't have to create the temp table or specify the columns first, just select into the temp table and it will be created on the fly.
It sounds like you want to do something more than this... I can't quite figure out what that is, but it sounds like maybe selecting all of your data from various tables into a single temp table (I don't know why you would want to do this)... If that's the case then UNION or UNION ALL should work. You can still use these with the dynamically created temp table.
Select coloum1,coloum2,coloum3,coloum4
INTO #Table3
FROM Database3.Table3
WHERE --Some Condition
UNION
Select column1, column2, column3, null
FROM Database1.Table1
WHERE --Some condition
The null above is just to give the 2nd select the same number of columns as the first (I used both selects from your post); this is a requirement for UNION.
Related
I have a simple SQL insert on Snowflake:
insert into table(
column1,
column2,
column3,
column4,
column5)
select
substring(data_string,1,3),
substring(data_string,4,3),
substring(data_string,7,3),
current_timestamp,
'1'
from table1
Select gives me ~690K records but it inserts only ~334K records. When I delete ~200K records from table it still inserts less.
There are no duplicates.
Columns are the right size.
I am not able to post the data because of the security.
So I am just asking if someone had the similar problem and the solution?
I know how to generate scripts to script insert lines allowing me to backup some data. I was wondering though if it was possible to write a query (using WHERE clause as an example) to target a very small subset of data in a very large table?
In the end I want to generate a script that has a bunch of insert lines and will allow for inserting primary key values (where it normally would not let you).
SSMS will not let you to have the INSERT queries for specific rows in a table. You can do this by using GenerateInsert stored procedure. For example :
EXECUTE dbo.GenerateInsert #ObjectName = N'YourTableName'
,#SearchCondition='[ColumnName]=ColumnValue';
will give you similar result for the filtered rows specified in the #SearchCondition
Let's say your table name is Table1 which has columns Salary & Name and you want the insert queries for those who have salary greater than 1000 whose name starts with Mr., then you can use this :
EXECUTE dbo.GenerateInsert #ObjectName = N'Table1'
,#SearchCondition='[Salary]>1000 AND [Name] LIKE ''Mr.%'''
,#PopulateIdentityColumn=1;
If I read your requirement correctly, what you actually want to do is simply make a copy of some data in your table. I typically do this by using a SELECT INTO. This will also generate the target table for you.
CREATE TABLE myTable (Column1 int, column2 NVARCHAR(50))
;
INSERT INTO myTable VALUES (1, 'abc'), (2, 'bcd'), (3, 'cde'), (4, 'def')
;
SELECT * FROM myTable
;
SELECT
*
INTO myTable2
FROM myTable WHERE Column1 > 2
;
SELECT * FROM myTable;
SELECT * FROM myTable2;
DROP TABLE myTable;
DROP TABLE myTable2;
myTable will contain the following:
Column1 column2
1 abc
2 bcd
3 cde
4 def
myTable2 will only have the last 2 rows:
Column1 column2
3 cde
4 def
Edit: Just saw the bit about the Primary Key values. Does this mean you want to insert the data into an existing table, rather than just creating a backup set? If so, you can issue SET IDENTITY_INSERT myTable2 ON to allow for this.
However, be aware that might cause issues in case the id values you are trying to insert already exist.
In a SQL file, is it possible to insert multiple lines in multiple queries all at once? For example, I have a stored procedure SQL file that has several queries. Each query writes into a table the exact same way. It writes in the following way:
INSERT INTO some_table
SELECT
'some_value' AS column1,
'some_other_value' AS column2,
'another_value' AS column3
FROM source_table
....
I'm trying to add the following lines between the last column and the FROM clause:
'stuff' AS column4,
'more_stuff' AS column5
So, the final query will look like:
INSERT INTO some_table
SELECT
'some_value' AS column1,
'some_other_value' AS column2,
'another_value' AS column3,
'stuff' AS column4,
'more_stuff' AS column5
FROM source_table
....
While I can do this manually, it will be very time-consuming to do it for every query. Is there a way to do it for all queries at once?
In the find-replace method, I don't think I can do the following:
1) Find all lines that read
'some_stuff'
2) Replace each of the identified lines with the following set of multiple lines:
'some_stuff'
'more_stuff'
'yet_more_stuff'
I am trying to create an SQL script to insert a new row and use that row's identity column as an FK when inserting into another table.
This is what I use for a one-to-one relationship:
INSERT INTO userTable(name) VALUES(N'admin')
INSERT INTO adminsTable(userId,permissions) SELECT userId,255 FROM userTable WHERE name=N'admin'
But now I also have a one-to-many relationship, and I asked myself whether I can use less SELECT queries than this:
INSERT INTO bonusCodeTypes(name) VALUES(N'1500 pages')
INSERT INTO bonusCodeInstances(codeType,codeNo,isRedeemed) SELECT name,N'123456',0 FROM bonusCodeTypes WHERE name=N'1500 pages'
INSERT INTO bonusCodeInstances(codeType,codeNo,isRedeemed) SELECT name,N'012345',0 FROM bonusCodeTypes WHERE name=N'1500 pages'
I could also use sth like this:
INSERT INTO bonusCodeInstances(codeType,codeNo,isRedeemed)
SELECT name,bonusCode,0 FROM bonusCodeTypes JOIN
(SELECT N'123456' AS bonusCode UNION SELECT N'012345' AS bonusCode)
WHERE name=N'1500 pages'
but this is also a very complicated way of inserting all the codes, I don't know whether it is even faster.
So, is there a possibility to use a variable inside SQL statements? Like
var lastinsertID = INSERT INTO bonusCodeTypes(name) OUTPUT inserted.id VALUES(N'300 pages')
INSERT INTO bonusCodeInstances(codeType,codeNo,isRedeemed) VALUES(lastinsertID,N'123456',0)
OUTPUT can only insert into a table. If you're only inserting a single record, it's much more convenient to use SCOPE_IDENTITY(), which holds the value of the most recently inserted identity value. If you need a range of values, one technique is to OUTPUT all the identity values into a temp table or table variable along with the business keys, and join on that -- but provided the table you are inserting into has an index on those keys (and why shouldn't it) this buys you nothing over simply joining the base table in a transaction, other than lots more I/O.
So, in your example:
INSERT INTO bonusCodeTypes(name) VALUES(N'300 pages');
DECLARE #lastInsertID INT = SCOPE_IDENTITY();
INSERT INTO bonusCodeInstances(codeType,codeNo,isRedeemed) VALUES (#lastInsertID, N'123456',0);
SELECT #lastInsertID AS id; -- if you want to return the value to the client, as OUTPUT implies
Instead of VALUES, you can of course join on a table instead, provided you need the same #lastInsertID value everywhere.
As to your original question, yes, you can also assign variables from statements -- but not with OUTPUT. However, SELECT #x = TOP(1) something FROM table is perfectly OK.
I have a table with several columns (and thousands of rows). I am trying to make a new set of rows work over several shops, so I need to copy a group of rows, change one column, and then reinsert them into my table (the column I'm changing is a key, so that's not a problem).
So far, I've gotten to this point:
INSERT INTO TableName( Column1, Column2, Column3, Column4, Column5, Column6)
(SELECT Column1, Column2, Column3, Column4, Column5, 'NewShopCode'
FROM TableName
WHERE Column5 = 'DistinguishingValue'
For each new shop, I need to do this for two different 'DistinguishingValue's, and I have about ten different 'NewShopCode's.
I have tried ('NewShopCode1', 'NewShopCode2') in place of the single literal insert above, as well as using VALUES before my SELECT statement. Neither of these work, returning a syntax error in each case.
Also, while, in this instance, it's not too much of a hassle to just do two separate queries for DV1 and 2, it would be nice if I could incorporate that into the one single query as well.
For clarification, I know I could just do the query 10 times with copy and paste and it would be pretty quick, and I totally would if it were just a database that I used around my office. Unfortunately, this is an update I need to script and send out to all my customers with the next version release of our software; ergo, single query = less phone calls complaining about how nobody's database works since it didn't update correctly.
Thanks in advance for your consideration.
Use a cross join. You didn't say what version of SQL you were using, so I'll low-ball it:
INSERT INTO TableName( Column1, Column2, Column3, Column4, Column5, Column6)
(SELECT Column1, Column2, Column3, Column4, Column5, a.[sc]
FROM TableName as t
cross join (
select 'NewShopCode1' as [sc]
union
select 'NewShopCode2' as [sc]
union
select 'NewShopCode3' as [sc]
) as a
WHERE Column5 = 'DistinguishingValue'
and not exists (select 1 from TableName as t where t.Column1 = a.Column1 and t.Column2 = a.Column2)
)
Try the select by itself to see that it produces the correct results before inserting.