Copy, Insert and Update - tsql

I have inserted 9000 rows into the AcctHist table in the database. The LedgerID is 'HOME'. Now I need to copy these rows and insert them again into the same table, but with LedgedID = 'FIELD' (LedgerID is part of the Primary key). No other changes.
How can I achieve this ? Do I need to copy this data to excel, make the changes and then insert again?

Given that all rows with LedgerID = 'HOME' are the ones you inserted and the ones you need copied, this should work, swapping out <all other columns in AcctHist, comma delimited> with your actual column names. Note that if you have any identity fields, you should omit those, since they will be populated automatically.
INSERT INTO AcctHist
(
LedgerID,
<all other columns in AcctHist, comma delimited>
)
SELECT
'FIELD',
<all other columns in AcctHist, comma delimited>
FROM AcctHist WHERE LedgerID = 'HOME'

Related

Unable to skip a line from Excel while doing copy activity in azure data factory

I have a excel Column as a source in Copy Activity. I need to map the columns from source to sink (MS SQL Server).
I have one constraint, whenever I have a blank row in the excel source I should Stop the copy Activity.
I want to copy all the column data before the blank row, and ignore what ever after the blank row.
For example if I have this dataset:
A
B
ABC
DEF
HIJ
KLM
NOP
QRS
Then the first two rows should be imported and the last two rows should not be imported.
What should I do?
In an ADF pipeline there are limited options for working with the contents of datasets (you can add cols, remove cols, etc) but modifying the rows themselves is hard. You can do it with dataflows but as your sink is mssqlserver then you can use row_number() to find any empty rows and keep the rows up to the blank row.
The process is:
Create a staging table which is the same as the target table but includes a row column that is defined row INT IDENTITY(1,1) NOT NULL
Truncate the staging table
Write the data to a staging table
From the staging table write to the main table using the insert query:
SELECT * FROM staging_table
WHERE rowid <
(SELECT
COALESCE(MIN(rowid), (SELECT MAX(rowid)+1 FROM staging_table)) FROM staging_table WHERE a IS NULL)

How can I copy an IDENTITY field?

I’d like to update some parameters for a table, such as the dist and sort key. In order to do so, I’ve renamed the old version of the table, and recreated the table with the new parameters (these can not be changed once a table has been created).
I need to preserve the id field from the old table, which is an IDENTITY field. If I try the following query however, I get an error:
insert into edw.my_table_new select * from edw.my_table_old;
ERROR: cannot set an identity column to a value [SQL State=0A000]
How can I keep the same id from the old table?
You can't INSERT data setting the IDENTITY columns, but you can load data from S3 using COPY command.
First you will need to create a dump of source table with UNLOAD.
Then simply use COPY with EXPLICIT_IDS parameter as described in Loading default column values:
If an IDENTITY column is included in the column list, the EXPLICIT_IDS
option must also be specified in the COPY command, or the COPY command
will fail. Similarly, if an IDENTITY column is omitted from the column
list, and the EXPLICIT_IDS option is specified, the COPY operation
will fail.
You can explicitly specify the columns, and ignore the identity column:
insert into existing_table (col1, col2) select col1, col2 from another_table;
Use ALTER TABLE APPEND twice, first time with IGNOREEXTRA and the second time with FILLTARGET.
If the target table contains columns that don't exist in the source
table, include FILLTARGET. The command fills the extra columns in the
source table with either the default column value or IDENTITY value,
if one was defined, or NULL.
It moves the columns from one table to another, extremely quickly; took me 4s for 1GB table in dc1.large node.
Appends rows to a target table by moving data from an existing source
table.
...
ALTER TABLE APPEND is usually much faster than a similar CREATE TABLE
AS or INSERT INTO operation because data is moved, not duplicated.
Faster and simpler than UNLOAD + COPY with EXPLICIT_IDS.

Inserting multiple records and updating identity column in SQL

i have to insert multiple records into a table and in the mean time needed to insert the identity column of the first table in to another table.Can i do it avoiding loop?
Edited
i have two tables named StudentMaster and StudentSujects.
First Table structure is (StudentID int Identity(1,1),StudentName varchar(100))
Second table structure is (SubjectID int Identity(1,1),StudentID int,SubjectName varchar(100)).
StudentID in the 'StudentSujects' table is the Identity column of first table 'StudentMaster'.
INSERT INTO StudentMaster
(
StudentName
)
SELECT StudentName
FROM OPENXML(#hDoc,'/XML/Students')
WITH( StudentName varchar(100) 'StudentName')
I am inserting multiple records in to the first table using the above query.I the mean time i have to insert the identity column of each row in to the second table.
You can use the OUTPUT clause to output multiple columns/rows on an INSERT operation into a table variable.
Assuming your table that you're inserting into has an IDENTITY column called ID, you could have code something like this:
DECLARE #InsertedData TABLE (NewID INT, SomeOtherColumn.....)
INSERT INTO dbo.YourTable(Col1, Col2, ..., ColN)
OUTPUT INTO #InsertedData(NewID, SomeOtherColumn) Inserted.ID, Inserted.OtherColumn
VALUES(Val11, Val12, ..., Val1N),
(Val21, Val22, ..., Val2N),
....
(ValM1, ValM2, ..., ValMN)
Of course, you need to have something that allows you to identify which row in your second table to insert which value into - that's entirely dependent on your situation (and you didn't offer any explanation of that in your question).
But basically, using the OUTPUT clause, you can capture as much information as you need, including the newly assigned IDENTITY values, so that you can then do your second insert based on that information.

Insert into table with Identity and foreign key columns

I was trying to insert values from one table to another from two different databases.
My issue is I have two tables with a relation and the first table is having an identity column also.
eg table first(id, Name) - table second(id, address)
So now both the table exist with values in a db and i am trying to copy values from this db to another db.
So when I insert values from first db to second db the the first table will insert values for the Id column by itself so now I have to link that id to the second table.
How can I do that?
UPDATE using MSSQL server 2000
You can use #scope_identity immediately after your insert in SQL server 2000 which will give you the last id within the current scope but I'm not sure how that would work with bulk inserting of data
http://msdn.microsoft.com/en-us/library/ms190315.aspx
If this were SQL Server 2005 or later I would suggest using the output clause in your insert statement to retrieve the ids just inserted, but that was not available in SQL Server 2000.
If your data contains some column or series of columns which is unique other than the identity column, then you can query your first table based on that series of columns to get the ids and use that to populate your second table.
If the target tables were empty you could use SET IDENTITY_INSERT ON - this would allow to insert original values to identity columns, and you will not have to update referenced IDs. Of course if there is any existing ids that can overlap inserted ids - that is not the solution.
If names in first tables are unique, you could boild mapping between new and old ids and perform update something like this:
UPDATE S
SET S.id = F.id
FROM second S
INNER JOIN first_original FO ON FO.id = S.id
INNER JOIN first F ON F.name = FO.name
If names are not unique, then original ids should be saved in "first" in order to provide mapping between old and new ids. It can be temporary new column that can be deleted after ids in "second" will be updated.
Or as Rich Andrews said you could use #scope_identity, but in this case you will have to perform insert one by one - declare a cursor on source table, insert each record, get its new id and insert it into "second" table.

Is there a way to quickly duplicate record in T-SQL?

I need to duplicate selected rows with all the fields exactly same except ID ident int which is added automatically by SQL.
What is the best way to duplicate/clone record or records (up to 50)?
Is there any T-SQL functionality in MS SQL 2008 or do I need to select insert in stored procedures ?
The only way to accomplish what you want is by using Insert statements which enumerate every column except the identity column.
You can of course select multiple rows to be duplicated by using a Select statement in your Insert statements. However, I would assume that this will violate your business key (your other unique constraint on the table other than the surrogate key which you have right?) and require some other column to be altered as well.
Insert MyTable( ...
Select ...
From MyTable
Where ....
If it is a pure copy (minus the ID field) then the following will work (replace 'NameOfExistingTable' with the table you want to duplicate the rows from and optionally use the Where clause to limit the data that you wish to duplicate):
SELECT *
INTO #TempImportRowsTable
FROM (
SELECT *
FROM [NameOfExistingTable]
-- WHERE ID = 1
) AS createTable
-- If needed make other alterations to the temp table here
ALTER TABLE #TempImportRowsTable DROP COLUMN Id
INSERT INTO [NameOfExistingTable]
SELECT * FROM #TempImportRowsTable
DROP TABLE #TempImportRowsTable
If you're able to check the duplication condition as rows are inserted, you could put an INSERT trigger on the table. This would allow you to check the columns as they are inserted instead of having to select over the entire table.