SQL server--> Inserting multiple rows into a table with identity column - sql

I wanna insert a multiple rows into a table with identity column
I have a table called 'STU' with the following columns:
SNO (Primary Key, and Identity [i.e. autoincrementing])
NAME (not null)
CLASS (not null)
SECTION (not null)
CREATE TABLE STU (SNO INT IDENTITY (1,1) CONSTRAINT PK_SNO PRIMARY KEY (SNO),
NAME VARCHAR(25), CLASS VARCHAR(20), SECTION CHAR );
The values are got inserted while executing insert query for each row individually
INSERT INTO STU VALUES('A','1','A');
INSERT INTO STU VALUES('B','2','B');
INSERT INTO STU VALUES('C','3','C');
INSERT INTO STU VALUES('D','4','D');
INSERT INTO STU VALUES('E','5','E');
but while trying to insert multiple values using single insert query in every possible shots, it took throws an error
INSERT INTO STU (SNO,NAME,CLASS,SECTION)
VALUES(NULL,NULL,NULL,NULL)
,('A','B','C','D','E','F')
,('1','2','3','4','5','6')
,('A','B','C','D','E','F');
also
INSERT INTO STU (NAME,CLASS,SECTION) VALUES
('A','B','C','D','E','F'),
('1','2','3','4','5','6'),
('A','B','C','D','E','F');
also
INSERT INTO STU (NAME,CLASS,SECTION) VALUES
('A','1','A'),
('B','2','A'),('C','3','A'),
('D','4','D'),
('E','5','E'),
('F','6','F');
also
INSERT INTO STU (SNO,NAME,CLASS,SECTION) VALUES
(NULL,'A','1','A'),
(NULL,'B','2','A'),
(NULL,'C','3','A'),
(NULL,'D','4','D'),
(NULL,'E','5','E'),
(NULL,'F','6','F');

All your Insert statements are bad:
Make sure you are supplying the same number of columns as in the INSERT statement
Make sure you are not supplying SNO (it's automatic)
Here is an example:
INSERT INTO STU (NAME,CLASS,SECTION) VALUES
('A','B','C'),
('1','2','3'),
('A','B','C');

If you are on SQL Server 2005, use UNION ALL
INSERT STU (NAME,CLASS,SECTION)
SELECT 'A' AS NAME,'1' AS CLASS, 'A' AS SECTION
UNION ALL
SELECT 'B', '2', 'B'
UNION ALL
SELECT 'C', '3', 'C'
Versions later than 2005, you could use
INSERT STU (NAME,CLASS,SECTION)
VALUES ('A','1','A'),
('B','2','B'), ...

You just need to concatenate the SQL you had in your first example.
You can't insert into the identity column (unless you turn identity insert on of course).
INSERT INTO STU (NAME,CLASS,SECTION)
VALUES
('A','1','A'),
('B','2','A'),
('C','3','A'),
('D','4','D'),
('E','5','E'),
('F','6','F');
If you do want to turn identity insert on then you'd need to do the following:
SET IDENTITY_INSERT STU ON
INSERT INTO STU (SNO, NAME,CLASS,SECTION)
VALUES
(1, 'A','1','A'),
(2, 'B','2','A'),
(3, 'C','3','A'),
(4, 'D','4','D'),
(5, 'E','5','E'),
(6, 'F','6','F');
SET IDENTITY_INSERT STU OFF
SQL Fiddle

You can write this as:
INSERT INTO STU VALUES
('A','1','A'),
('B','2','B'),
('C','3','C'),
('D','4','D'),
('E','5','E');

Related

Leveraging CHECKSUM in MERGE but unable to get all rows to merge

I am having trouble getting MERGE statements to work properly, and I have recently started to try to use checksums.
In the toy example below, I cannot get this row to insert (1, 'ANDREW', 334.3) that is sitting in the staging table.
DROP TABLE TEMP1
DROP TABLE TEMP1_STAGE
-- create table
CREATE TABLE TEMP1
(
[ID] INT,
[NAME] VARCHAR(55),
[SALARY] FLOAT,
[SCD] INT
)
-- create stage
CREATE TABLE TEMP1_STAGE
(
[ID] INT,
[NAME] VARCHAR(55),
[SALARY] FLOAT,
[SCD] INT
)
-- insert vals into stage
INSERT INTO TEMP1_STAGE (ID, NAME, SALARY)
VALUES
(1, 'ANDREW', 333.3),
(2, 'JOHN', 555.3),
(3, 'SARAH', 444.3)
-- insert stage table into main table
INSERT INTO TEMP1
SELECT *
FROM TEMP1_STAGE;
-- clean up stage table
TRUNCATE TABLE TEMP1_STAGE;
-- put some new values in the stage table
INSERT INTO TEMP1_STAGE (ID, NAME, SALARY)
VALUES
(1, 'ANDREW', 334.3),
(4, 'CARL', NULL)
-- CHECKSUMS
update TEMP1_STAGE
set SCD = binary_checksum(ID, NAME, SALARY);
update TEMP1
set SCD = binary_checksum(ID, NAME, SALARY);
-- run merge
MERGE TEMP1 AS TARGET
USING TEMP1_STAGE AS SOURCE
-- match
ON (SOURCE.[ID] = TARGET.[ID])
WHEN NOT MATCHED BY TARGET
THEN INSERT (
[ID], [NAME], [SALARY], [SCD]) VALUES (
SOURCE.[ID], SOURCE.[NAME], SOURCE.[SALARY], SOURCE.[SCD]);
-- the value: (1, 'ANDREW', 334.3) is not merged in
SELECT * FROM TEMP1;
How can I use the checksum to my advantage in the MERGE?
Your issue is that the NOT MATCHED condition is only considering the ID values specified in the ON condition.
If you want duplicate, but distinct records, include SCD to the ON condition.
If (more likely) your intent is that record ID = 1 be updated with the new SALARY, you will need to add a WHEN MATCHED AND SOURCE.SCD <> TARGET.SCD THEN UPDATE ... clause.
That said, the 32-bit int value returned by the `binary_checksum()' function is not sufficiently distinct to avoid collisions and unwanted missed updates. Take a look at HASHBYTES instead. See Binary_Checksum Vs HashBytes function.
Even that may not yield your intended performance gain. Assuming that you have to calculate the hash for all records in the staging table for each update cycle, you may find that it is simpler to just compare each potentially different field before the update. Something like:
WHEN MATCHED AND (SOURCE.NAME <> TARGET.NAME OR SOURCE.SALARY <> TARGET.SALARY)
THEN UPDATE ...
Even then, you need to be careful of potential NULL values and COLLATION. Both NULL <> 50000.00 and 'Andrew' <> 'ANDREW' may not give you the results you expect. It might be easiest and most reliable to just code WHEN MATCHED THEN UPDATE ....
Lastly, I suggest using DECIMAL instead of FLOAT for Salary.

Oracle SQL Plus not all table columns displayed

I've created this table :
CREATE TABLE PRODUCT (
P_CODE CHAR(8),
P_DESCRIPT CHAR(200),
P_INDATE CHAR(20),
P_ONHAND INTEGER,
P_MIN INTEGER,
P_PRICE NUMBER,
P_DISCOUNT NUMBER,
V_CODE CHAR(5)
);
And I've inserted the following data in the table:
INSERT INTO PRODUCT VALUES ('11QER/31','Power painter, 15 psi, 3-nozzle','12/2/96',8,5,109.99,0.00,25595);
INSERT INTO PRODUCT VALUES ('13-Q2/P2','7.25-in. pwr. Saw blade','11/12/96',32,15,14.99,0.05,21344);
INSERT INTO PRODUCT VALUES ('14-Q1/L3','9.00-in. pwr. Saw blade','11/12/96',18,12,17.49,0.00,21344);
INSERT INTO PRODUCT VALUES ('156-QQ2','Hrd. Cloth, 1/4-in., 2x50','8/14/96',15,8,39.95,0.00,23119);
INSERT INTO PRODUCT VALUES ('1558-QW1','Hrd. Cloth, 1/2-in., 3x50','8/14/96',23,5,43.99,0.00,23119);
INSERT INTO PRODUCT VALUES ('2232/QTY','B&D jigsaw, 12-in, blade','10/29/96',8,5,109.92,0.05,24288);
INSERT INTO PRODUCT VALUES ('2232/QWE','B&D jigsaw, 8-in, blade','9/23/96',6,5,99.87,0.05,24288);
INSERT INTO PRODUCT VALUES ('2238/QPD','B&D cordless drill, 1/2-in.','10/19/96',12,5,38.95,0.05,25595);
INSERT INTO PRODUCT VALUES ('23109-HB','Claw hammer','11/19/96',23,10,9.95,0.10,21225);
INSERT INTO PRODUCT VALUES ('23114-AA','Sledge hammer, 12 lb.','12/1/96',8,5,14.40,0.05,null);
INSERT INTO PRODUCT VALUES ('54778-2T','Rat-tail file, 1/8-in. fine','6/14/96',43,20,4.99,0.00,'21344');
INSERT INTO PRODUCT VALUES ('89-WRE-Q','Hicut chain saw, 16 in.','7/6/96',11,5,256.99,0.05,'24288');
INSERT INTO PRODUCT VALUES ('PVC23DAT','PVC pipe, 3.5-in., 8-ft','12/19/96',188,75,5.87,0.00,null);
INSERT INTO PRODUCT VALUES ('SM-18277','1.25-in. metal screw, 25','11/28/96',172,75,6.99,0.00,'21225');
INSERT INTO PRODUCT VALUES ('SW-23116','2.5-in. wd. screw, 50','9/23/96',237,100,8.45,0.00,'21231');
INSERT INTO PRODUCT VALUES ('WR3/TT3','Steel matting, 4''x8''x1/6", .5" mesh','11/16/96',18,5,119.95,0.10,'25595');
INSERT INTO PRODUCT VALUES ('11QER/31','Power painter, 15 psi, 3-nozzle','12/2/96',8,5,109.99,0.00,25595);
INSERT INTO PRODUCT VALUES ('13-Q2/P2','7.25-in. pwr. Saw blade','11/12/96',32,15,14.99,0.05,21344);
INSERT INTO PRODUCT VALUES ('14-Q1/L3','9.00-in. pwr. Saw blade','11/12/96',18,12,17.49,0.00,21344);
INSERT INTO PRODUCT VALUES ('156-QQ2','Hrd. Cloth, 1/4-in., 2x50','8/14/96',15,8,39.95,0.00,23119);
INSERT INTO PRODUCT VALUES ('1558-QW1','Hrd. Cloth, 1/2-in., 3x50','8/14/96',23,5,43.99,0.00,23119);
INSERT INTO PRODUCT VALUES ('2232/QTY','B&D jigsaw, 12-in, blade','10/29/96',8,5,109.92,0.05,24288);
INSERT INTO PRODUCT VALUES ('2232/QWE','B&D jigsaw, 8-in, blade','9/23/96',6,5,99.87,0.05,24288);
INSERT INTO PRODUCT VALUES ('2238/QPD','B&D cordless drill, 1/2-in.','10/19/96',12,5,38.95,0.05,25595);
INSERT INTO PRODUCT VALUES ('23109-HB','Claw hammer','11/19/96',23,10,9.95,0.10,21225);
INSERT INTO PRODUCT VALUES ('23114-AA','Sledge hammer, 12 lb.','12/1/96',8,5,14.40,0.05,null);
INSERT INTO PRODUCT VALUES ('54778-2T','Rat-tail file, 1/8-in. fine','6/14/96',43,20,4.99,0.00,'21344');
INSERT INTO PRODUCT VALUES ('89-WRE-Q','Hicut chain saw, 16 in.','7/6/96',11,5,256.99,0.05,'24288');
INSERT INTO PRODUCT VALUES ('PVC23DAT','PVC pipe, 3.5-in., 8-ft','12/19/96',188,75,5.87,0.00,null);
INSERT INTO PRODUCT VALUES ('SM-18277','1.25-in. metal screw, 25','11/28/96',172,75,6.99,0.00,'21225');
INSERT INTO PRODUCT VALUES ('SW-23116','2.5-in. wd. screw, 50','9/23/96',237,100,8.45,0.00,'21231');
INSERT INTO PRODUCT VALUES ('WR3/TT3','Steel matting, 4''x8''x1/6", .5" mesh','11/16/96',18,5,119.95,0.10,'25595');
now when I do the following:
SELECT * FROM PRODUCT;
only the first 4 columns is returned!
I tried setting the following:
SET WRAP ON
SET TERMOUT OFF
SET VERIFY OFF
SET TRIMSPOOL OFF
SET LINESIZE 2000
SET LONG 200000
SET PAGES 0
And now only two columns appear.
Please help.
If the column should be CHAR(200), then you should leave it alone - don't change it to CHAR(50) only because you can't display it properly.
Instead, you are probably OK by showing only the first 50 characters when you query the table. You could do that in the query itself, like this:
select p_code, substr(p_descript, 1, 50) as p_descript, p_indate, ...
Alternatively, you can tell SQL Plus to display the column in 50-character width, with a SQL Plus command - you were trying to do that, you just didn't find the right command. It is the column command; specifically in this case:
column p_descript format a50
(note this is NOT followed by semicolon ; since it is not a SQL command) This will wrap the values that are actually longer than 50 characters. If instead you want them to be truncated, issue an additional SQL Plus command:
set wrap off

SSRS: How do I display a list of customers, from A - K then L to Z, without having two separate reports?

I would like one report with a drop down menu, showing:
Customers A-K,
Customers L-Z
All Customers
I have an SQL table for customers, with the standard columns (Acc No., name, address, etc).
I would like this split by name as it takes a long time to bring the result of the entire table down.
I would prefer this to be in one report. Is this possible? I am using SQL Server 2008 R2 with reporting services.
I have tried a few different methods with no luck, so I'm open to any suggestions!
Thanks for reading my question and thanks in advance if you can find the time to help!
Please feel free to ask any questions.
create table #alphab
( alphaname varchar(15));
insert into #alphab VALUES ('ANT')
insert into #alphab values ('CAT')
insert into #alphab values ('pAT')
insert into #alphab values ('mAT')
insert into #alphab values ('dAT')
insert into #alphab values ('rAT')
insert into #alphab values ('dAT')
insert into #alphab values ('lAT')
insert into #alphab values ('cAT')
insert into #alphab values ('zAT')
insert into #alphab values ('xAT')
insert into #alphab values ('wAT')
insert into #alphab values ('oAT')
insert into #alphab values ('sAT')
insert into #alphab values ('yAT')
insert into #alphab values ('uAT')
select alphaname
from #alphab
where alphaname LIKE
CASE
WHEN #alphabetorder = 1 THEN ('[A-K | a-k]%')
WHEN #alphabetorder= 2 THEN ('[L-Z | l-z]%')
END
order by alphaname

How to to get the value of an auto increment column in postgres from a .sql script file?

In postgres I have two tables like so
CREATE TABLE foo (
pkey SERIAL PRIMARY KEY,
name TEXT
);
CREATE TABLE bar (
pkey SERIAL PRIMARY KEY,
foo_fk INTEGER REFERENCES foo(pkey) NOT NULL,
other TEXT
);
What I want to do is to write a .sql script file that does the following
INSERT INTO foo(name) VALUES ('A') RETURNING pkey AS abc;
INSERT INTO bar(foo_fk,other) VALUES
(abc, 'other1'),
(abc, 'other2'),
(abc, 'other3');
which produces the error below in pgAdmin
Query result with 1 row discarded.
ERROR: column "abc" does not exist
LINE 3: (abc, 'other1'),
********** Error **********
ERROR: column "abc" does not exist
SQL state: 42703
Character: 122
Outside of a stored procedure how do a define a variable that I can use between statements? Is there some other syntax for being able to insert into bar with the pkey returned from the insert to foo.
You can combine the queries into one. Something like:
with foo_ins as (INSERT INTO foo(name)
VALUES ('A')
RETURNING pkey AS foo_id)
INSERT INTO bar(foo_fk,other)
SELECT foo_id, 'other1' FROM foo_ins
UNION ALL
SELECT foo_id, 'other2' FROM foo_ins
UNION ALL
SELECT foo_id, 'other3' FROM foo_ins;
Other option - use an anonymous PL/pgSQL block like:
DO $$
DECLARE foo_id INTEGER;
BEGIN
INSERT INTO foo(name)
VALUES ('A')
RETURNING pkey INTO foo_id;
INSERT INTO bar(foo_fk,other)
VALUES (foo_id, 'other1'),
(foo_id, 'other2'),
(foo_id, 'other3');
END$$;
You can use lastval() to ...
Return the value most recently returned by nextval in the current session.
This way you do not need to know the name of the seqence used.
INSERT INTO foo(name) VALUES ('A');
INSERT INTO bar(foo_fk,other) VALUES
(lastval(), 'other1')
, (lastval(), 'other2')
, (lastval(), 'other3')
;
This is safe because you control what you called last in your own session.
If you use a writable CTE as proposed by #Ihor, you can still use a short VALUES expression in the 2nd INSERT. Combine it with a CROSS JOIN (or append the CTE name after a comma (, ins) - same thing):
WITH ins AS (
INSERT INTO foo(name)
VALUES ('A')
RETURNING pkey
)
INSERT INTO bar(foo_fk, other)
SELECT ins.pkey, o.other
FROM (
VALUES
('other1'::text)
, ('other2')
, ('other3')
) o(other)
CROSS JOIN ins;
Another option is to use currval
INSERT INTO foo
(name)
VALUES
('A') ;
INSERT INTO bar
(foo_fk,other)
VALUES
(currval('foo_pkey_seq'), 'other1'),
(currval('foo_pkey_seq'), 'other2'),
(currval('foo_pkey_seq'), 'other3');
The automatically created sequence for serial columns is always named <table>_<column>_seq
Edit:
A more "robust" alternative is to use pg_get_serial_sequence as Igor pointed out.
INSERT INTO bar
(foo_fk,other)
VALUES
(currval(pg_get_serial_sequence('public.foo', 'pkey')), 'other1'),
(currval(pg_get_serial_sequence('public.foo', 'pkey')), 'other2'),
(currval(pg_get_serial_sequence('public.foo', 'pkey')), 'other3');

Not in In SQL statement?

I have set of ids in excel around 5000 and in the table I have ids around 30000. If I use 'In' condition in SQL statment I am getting around 4300 ids from what ever I have ids in Excel. But If I use 'Not In' with Excel id. I have getting around 25000+ records. I just to find out I am missing with Excel ids in the table.
How to write sql for this?
Example:
Excel Ids are
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
Table has IDs
1,
2,
3,
4,
6,
8,
9,
11,
12,
14,
15
Now I want get 5,7,10 values from Excel which missing the table?
Update:
What I am doing is
SELECT [GLID]
FROM [tbl_Detail]
where datasource = 'China' and ap_ID not in (5206896,
5206897,
5206898,
5206899,
5117083,
5143565,
5173361,
5179096,
5179097,
5179150)
Try this:
SELECT tableExcel.ID
FROM tableExcel
WHERE tableExcel.ID NOT IN(SELECT anotherTable.ID FROM anotherTable)
Here's an SQL Fiddle to try this: sqlfiddle.com/#!6/31af5/14
You're probably looking for EXCEPT:
SELECT Value
FROM #Excel
EXCEPT
SELECT Value
FROM #Table;
Edit:
Except will
treat NULL differently(NULL values are matching)
apply DISTINCT
unlike NOT IN
Here's your sample data:
declare #Excel Table(Value int);
INSERT INTO #Excel VALUES(1);
INSERT INTO #Excel VALUES(2);
INSERT INTO #Excel VALUES(3);
INSERT INTO #Excel VALUES(4);
INSERT INTO #Excel VALUES(5);
INSERT INTO #Excel VALUES(6);
INSERT INTO #Excel VALUES(7);
INSERT INTO #Excel VALUES(8);
INSERT INTO #Excel VALUES(9);
INSERT INTO #Excel VALUES(10);
declare #Table Table(Value int);
INSERT INTO #Table VALUES(1);
INSERT INTO #Table VALUES(2);
INSERT INTO #Table VALUES(3);
INSERT INTO #Table VALUES(4);
INSERT INTO #Table VALUES(6);
INSERT INTO #Table VALUES(8);
INSERT INTO #Table VALUES(9);
INSERT INTO #Table VALUES(11);
INSERT INTO #Table VALUES(12);
INSERT INTO #Table VALUES(14);
INSERT INTO #Table VALUES(15);
Import your excel file into SQL Server using the Import Data Wizard found in SQL Server Management Studio.
Then you can write the following query to find any IDs which are in the file but not in the table:
SELECT id
FROM imported_table
WHERE id NOT IN (SELECT id FROM db_table)
You should move excel data to a table in SQL Server, and then do the query in SQL Server.
select distinct id from Excel where id not in (select your ids from Sqltable)
(Obviously select your ids from Sqltable is a select which returns the Ids existing on SQL Server).
You may think that moving data to SQL Server is hard to do, but, on the contrary, it's very easy:
1) create a table
CREATE TABLE ExcelIds (Id int)
2) add a new column in excel with the following formula:
="insert into ExcelIds values(" & XX & ")"
where XX is the reference to the cell in the column with excel Ids.
3) copy the "inserts" from Excel into SSMS or whatever tool you're usin in SQL Server, and execute them.
Now you have 2 tables in SQL Server, so that querying it is absolutely easy.
When you're over, just drop the table
DROP TABLE ExcelIds
NOTE: I didn't create a key on SQL Server table because I suppose that the Ids can be repeated. Neither is justified to create a more complex SQL Query to avoid duplicates in ExcelIds for this ad hoc solution.