BULK INSERT into table and auto-increment - sql-server

I have a .txt file in the format:
123456
111111
122222
123344
121212
I wish to insert these into a temporary table along with an integer recording the order in which they are in the .txt file, such as:
Index Number
---------------
1 123456
2 111111
3 122222
4 123344
5 121212
Currently I'm doing this by having an IDENTITY column in my temporary table and doing a BULK INSERT using a FORMATFILE like so:
CREATE TABLE #tbl
(
idx int NOT NULL IDENTITY,
ItemNumber nchar(6)
)
BULK INSERT #tbl
FROM 'd:\MyNumberList.txt'
WITH
(
FORMATFILE='d:\MyFormatFile.xml'
)
However, I'm hoping theres a way of achieving this without the need for a FORMATFILE file.
Is there a way of doing this?

You can do this with a view. However, because you are using a temporary table here, and it's not possible to create a view on a temporary table, you'd addtionally need to make use of a synonym.
If you were importing into a regular table, you wouldn't need the synonym:
create synonym tbl for #tbl
GO
create view vtbl
as
select ItemNumber from tbl
GO
bulk insert vtbl from 'd:\MyNumberList.txt'
GO
select * from #tbl
GO

Related

T-SQL OUTPUT clause to update a temp table

I have a utility script that is used to insert data into tables in my database. The script has a number of temp table in it that stores the new data to be inserted and a lot of it is related.
So, for example I have tables like so
DECLARE #Table1 TABLE
(
Table1ID INT
Table1Description VARCHAR(50)
Table1Code VARCHAR(5)
)
DECLARE #Table2 TABLE
(
Table2ID INT
Table2Description VARCHAR(50)
Table2Code VARCHAR(5)
)
DECLARE #Relationships TABLE
(
Table1Code VARCHAR(5)
Table2Code VARCHAR(5)
)
So the script populates the data in #Table1 and #Table2, but doesn't populate the ID fields. Once the data has been MERGEd into the database tables, I update the Table1ID and Table2ID fields in a separate statement as they are auto incrementing fields. Then when I use the #Relationships table to populate the database table, I can join to #Table1 and #Table2 to get the actual ID values.
I'm updating the script and I'm wondering if I can MERGE the data from #Table1/#Table2 into the database and update the ID fields in the temp table as part of the MERGE statement using the OUTPUT clause all in one statement?
I think the answer is no as I can't find anything mentioning updating an existing table with the OUTPUT clause, only inserting into a table.
I am still able to do what I need to do, so I'm not after alternatives. I just wondering if it is possible using the OUTPUT Clause
Thanks in advance

How can we completely replace the contents of a table with another table in a SQL Server database?

How can we completely replace the contents of a table with another table in a SQL Server database?
Like Truncate. We want to take all the data in one and put the data in the other one into it. How can we do? How do we do it with a script? By doing this automatically.
It happens in Oracle, does it happen in SQL Server? Thanks.
Just make simple insert into statement like this :
Also you can create procedure that will makes like just my simple example
DECLARE #employee1 TABLE(
Emp VARCHAR(100),
DOB datetime
)
INSERT INTO #employee1 SELECT 'ABC','1991-03-01'
INSERT INTO #employee1 SELECT 'XYZ','1992-12-01'
INSERT INTO #employee1 SELECT 'AJM','1992-08-20'
INSERT INTO #employee1 SELECT 'RNM','1991-07-10'
DECLARE #employee2 TABLE(
Emp VARCHAR(100),
DOB datetime
)
INSERT INTO #employee2
select * from #employee1
select '#employee1',* from #employee1
select '#employee2',* from #employee2
SQLFiddleDemo
If i am correct schema is same for both tables. In this case there are many way you can achieve this automatically,
Option 1: Call Stored Procedure from any web page or window service or any api.
Option 2: Create triggers.
In both way you can use following script to copy data from one table to other:
Truncate table <table1>
GO
INSERT <Table1> (column1, column2)
SELECT Column1, column2 FROM <Table2>
GO

Get more than 1 id to new inserted row

I have this data.
I want to duplicate data like a picture above with stored procedure.
First thing I do is copying two rows in the first table. How can I get 2 (two) 'iId' in the first table to create 2 (two) rows in the second table and put those 'iId' into 'iId_JTS-Rule_RulePricingGroup' like the picture above?
I think you can use OUTPUT clause with INSERT
CREATE TABLE #Table1(
ID int IDENTITY PRIMARY KEY,
Title varchar(10)
)
CREATE TABLE #Table2(
ID int,
Title varchar(10)
)
DECLARE #NewIDs TABLE(ID int)
INSERT #Table1(Title)
OUTPUT inserted.ID INTO #NewIDs(ID) -- save new IDs
VALUES ('A'),('B'),('C')
INSERT #Table2(ID,Title)
SELECT ID,Title
FROM #Table1
WHERE ID IN(SELECT ID FROM #NewIDs) -- use new IDs
DROP TABLE #Table1
DROP TABLE #Table2

Temp tables: CREATE vs. SELECT INTO

I've searched and found this article about temporary tables in SQL Server because I've met a line in one of our stored procedures saying:
SELECT Value SomeId INTO #SomeTable FROM [dbo].[SplitIds](#SomeIds, ';')
I know that #SomeTable is stored in tempdb as a temporary table. However, I don't understand why we don't have to use CREATE TABLE #SomeTable first as it is written in the mentioned article. Our code is working fine, I just don't get why it is enough to use SELECT ... INTO #SomeTable. What would be the consequence when I add CREATE TABLE #SomeTable at the beginning? Would we get any differences in performance? Would the table be stored at another location?
Select ... into [table] uses the properties of the dataset generated from the Select statement to create a temporary table and subsequently fill the table.
The alternative to using Select ... into [table] is to use a Create Table statement followed by an Insert Into statement. Explicitly creating the table offers more control and precision.
Using a Select ... into [Table] may seem like a no-brainer, but there are situations where Select ... into [Table] can be problematic.
For instance, when you are going to create a temporary table and insert additional rows at a later time, using the Select ... into [Table] syntax can cause problems, especially with string-based and nullable fields.
As an example of the limitations of the Select ... into [table], the script below creates a temporary table with two fields, First_Name and Last_Name. Next, an Insert statement attempts to add another record to the temporary table, but fails as the values would be truncated.
Select 'Bob' as First_Name
, 'Smith' as Last_Name
Into #tempTable;
Insert into #tempTable (First_Name, Last_Name)
Select 'Christopher' as First_Name
, 'Brown' as Last_Name;
The script fails because the Select ... into [table] statement creates a table equivalent to the following script:
Create Table #tempTable (
First_Name varchar(3) Not Null
Last_Name varchar(5) Not Null
);

Set A Field the same as ID (IDENTITY) in the insert

I have a Code (int) in my table, the ID is set to identity. How can I set a default value for my code to be filled by the same value az ID? I mean Identity.
You could use an after insert trigger:
create table TestTable (id int identity, col1 int)
go
create trigger TestTrigger on TestTable after insert
as begin
update TestTable
set col1 = id
where col1 is null
and id in (select id from inserted)
end
go
Test code:
insert TestTable default values
insert TestTable (col1) values (666)
insert TestTable default values
select * from TestTable
In general, I try to stay clear of triggers. In the long run using a stored procedure for insert is much more maintainable:
create procedure dbo.InsertTestRow(
#col1 int)
as
insert TestTable (col1) values (#col1)
if #col1 is null
begin
update TestTable
set col1 = id
where id = SCOPE_IDENTITY()
end
If it always has the same value - why don't you just drop that field. Otherwise it can be maintained with triggers (BEFORE INSERT one).
I'm looking for something in the
default value! If it is null it should
be filled with the same value as id
but if it is provided with some value,
it should keep that value
You could solve the issue by using coalesce in your queries instead.
create table T (ID int identity, ID2 int)
insert into T values (default)
insert into T values (null)
insert into T values (78)
select
ID,
coalesce(ID2, ID) as ID2
from T
Result
ID ID2
-- ---
1 1
2 2
3 78
Assuming your table's ID is an Identity column, you could consider using a constraint:
ALTER TABLE MyTable
ADD CONSTRAINT MyTableCodeDefault
DEFAULT IDENT_CURRENT('MyTable') FOR Code
This works for these use cases:
INSERT INTO MyTable DEFAULT VALUES
INSERT INTO MyTable ({columns NOT including 'Code'})
VALUES ({value list matching insert columns})
INSERT INTO MyTable (Code) VALUES (666)
INSERT INTO MyTable (Code) SELECT 8 UNION SELECT 13 UNION SELECT 21
But it does not work for bulk inserts:
INSERT INTO MyTable ({columns NOT including 'Code'})
SELECT {value list matching insert columns}
UNION
SELECT {value list matching insert columns}
UNION
SELECT {value list matching insert columns}
This restriction may seem onerous, but in my practical experience, it's rarely a problem. Most of the use cases I've encountered that need a default value involve user/UI 'convenience': don't force the user to pick a value if they don't want to.
OTOH, rarely do I encounter bulk insert situations where it's impractical to specify the value for the columns you're targeting.
You could use computed column, like this:
if object_id('TempTable') is not null drop table TempTable
create table TempTable (Id int identity(1,1), Code as Id)
insert into TempTable
default values
insert into TempTable
default values
insert into TempTable
default values
select * from TempTable
Of course if you have other columns, then you dont need default values:
if object_id('TempTable') is not null drop table TempTable
create table TempTable (Id int identity(1,1), Code as Id, SomethingElse int)
insert into TempTable (SomethingElse)
select 10 union all
select 11 union all
select 12
select * from TempTable
But, like zerkms said - why do you need two columns that are same?
If the field is an Identity field in SQL Server, the database engine will take care of its value. What we normally do is to read the record back (after inserting) to get to the generated Id.
EDIT: It sounds like you are trying to "override" the identity? If so, before you insert, run:
SET IDENTITY_INSERT [tableName] ON
You'll have to be careful not to insert a value that already exists. This can get tricky, though. So maybe consider removing the identity property altogether, and managing the default values yourself?

Resources