I am using insert statement to insert data from oracle forms to database but instead of one row.. its inserting two rows automatically..?
I am using the following query:
insert into xx_book_grp3 ( BOOK_ID,AUTHOR_ID,ISBN,PAGES,PUBLISHING_DATE,BOOK_TYPE,COST,BOOK_NAME) values (xxtrn_grp3_book_id.nextval,:XX_BOOK_GRP3.AUTHOR_ID,:XX_BOOK_GRP3.ISBN,:XX_BOOK_GRP3.PAGES,:XX_BOOK_GRP3.PUBLISHING_DATE,
:XX_BOOK_GRP3.BOOK_TYPE,
:XX_BOOK_GRP3.COST,
:XX_BOOK_GRP3.BOOK_NAME);
commit;
Try this to prevent duplicate insert:
-- I think you can check for existing record on author_id and isbn or even isbn only is sufficient:
Declare
v_count number;
Begin
Select count(*) into v_count from xx_book_grp3
where author_id = :xx_book_grp3.author_id and isbn = :xx_book_grp3.isbn;
if v_count = 0 then
insert into xx_book_grp3 ( BOOK_ID,AUTHOR_ID,ISBN,PAGES,PUBLISHING_DATE,BOOK_TYPE,COST,BOOK_NAME) values (xxtrn_grp3_book_id.nextval,:XX_BOOK_GRP3.AUTHOR_ID,:XX_BOOK_GRP3.ISBN,:XX_BOOK_GRP3.PAGES,:XX_BOOK_GRP3.PUBLISHING_DATE,
:XX_BOOK_GRP3.BOOK_TYPE,
:XX_BOOK_GRP3.COST,
:XX_BOOK_GRP3.BOOK_NAME);
commit;
end if;
end;
First of all, make sure you have a primary key in your table. Please note: PK eliminates duplication.
I also suggest checking your form for any insert for the same table.
You may be have a database trigger or a database procedure which is called from by name inside any form trigger.
I have a stored procedure that returns a result set. After that I insert this result set into created real table. And then I am using that real table create SSRS reports.
So, something like this:
CREATE PROCEDURE Test
AS
DECLARE #TempTable TABLE(..)
INSERT INTO #TempTable
SELECT...
FROM ...
WHERE ...
SELECT * FROM #TempTable
--============================
INSERT INTO RealTable EXEC [dbo].[Test]
How can I modify this stored procedure so every time it executed it will truncate table with existing data and then insert a fresh one?
So I need something like that:
create procedure Test
as
TRUNCATE RealTable
DECLARE #TempTable TABLE(..)
INSERT INTO #TempTable
SELECT...
FROM...
WHERE...
SELECT * FROM #TempTable INTO RealTable
Or should I just create agent job that would run command something like:
Truncate Table RealTable
INSERT INTO RealTable EXEC [dbo].[Test]
Am I on a right way in terms of logic?
Dont TRUNCATE. Use a MERGE Statement.
CREATE PROCEDURE Test
AS
MERGE RealTable TRGT
USING SourceTable SRCE
ON SRCE.[Column] = TRGT.Column --use columns that can be joined together
WHEN MATCHED THEN UPDATE
SET TRGT.Column1 = SRCE.Column1,
TRGT.Column2 = SRCE.Column2
....................
WHEN NOT MATCHED BY TARGET THEN INSERT
VALUES
(
SRCE.Column1,
SRCE.Column2,
.....................
)
WHEN NOT MATCHED BY SOURCE THEN
DELETE;
What's the purpose of the truncate if you are inserting the same data?
What should happen if you have more then 1 concurrent user?
another thing you can do:
1.
insert into TargetTable
select * from SourceTable
2.
rebuild indexes on TargetTable
3.
exec sp_rename SourceTable, SourceTable_Old
exec sp_rename TargetTable, SourceTable
drop table SourceTable_Old
this is an old way of entire table data refresh without much impact, when table variable was not an option.
this is what you probably need as you are directly inserting from #TempTable to RealTable.
create procedure Test
as
BEGIN
TRUNCATE TABLE RealTable
INSERT INTO RealTable
SELECT...
FROM someothertable
WHERE...
END
I have a stored proc, SP1, which executes and does select on one table. Now i have the need to insert that data in another table. I dont want to duplicate the code so i thought of inserting the data returned by the SP1 in the temp table so i can do some processing on it and save it.
I tried INSERT INTO #tmp; exec dbo.Sp1; but it gives me an error saying Invalid object name '#tmp'.. Isnt there a way i can create this table dynamically? Is there a better solution to this problem?
The temp table has to exist before you can use insert into exec.
This is not such a draw back as it first seems as any changes to the procedure result set will likely brake your code.
first run this:
create proc MySelect
as
begin
select 1 as myColumn1, 2 as mycolumn2
end
and then this:
create table #tmp(
col_1 int,
col_2 int)
insert into #tmp exec MySelect
select * from #tmp
I inserted some values into a table. There is a column whose value is auto-generated. In the next statement of my code, I want to retrieve this value.
Can you tell me how to do it the right way?
##IDENTITY is not scope safe and will get you back the id from another table if you have an insert trigger on the original table, always use SCOPE_IDENTITY()
This is how I do my store procedures for MSSQL with an autogenerated ID.
CREATE PROCEDURE [dbo].[InsertProducts]
#id INT = NULL OUT,
#name VARCHAR(150) = NULL,
#desc VARCHAR(250) = NULL
AS
INSERT INTO dbo.Products
(Name,
Description)
VALUES
(#name,
#desc)
SET #id = SCOPE_IDENTITY();
This works very nicely in SQL 2005:
DECLARE #inserted_ids TABLE ([id] INT);
INSERT INTO [dbo].[some_table] ([col1],[col2],[col3],[col4],[col5],[col6])
OUTPUT INSERTED.[id] INTO #inserted_ids
VALUES (#col1,#col2,#col3,#col4,#col5,#col6)
It has the benefit of returning all the IDs if your INSERT statement inserts multiple rows.
If your using PHP and MySQL you can use the mysql_insert_id() function which will tell you the ID of item you Just instered.
But without your Language and DBMS I'm just shooting in the dark here.
Again no language agnostic response, but in Java it goes like this:
Connection conn = Database.getCurrent().getConnection();
PreparedStatement ps = conn.prepareStatement(insertSql, Statement.RETURN_GENERATED_KEYS);
try {
ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
rs.next();
long primaryKey = rs.getLong(1);
} finally {
ps.close();
}
If you are working with Oracle:
Inset into Table (Fields....) values (Values...) RETURNING (List of Fields...) INTO (variables...)
example:
INSERT INTO PERSON (NAME) VALUES ('JACK') RETURNING ID_PERSON INTO vIdPerson
or if you are calling from... Java with a CallableStatement (sry, it's my field)
INSERT INTO PERSON (NAME) VALUES ('JACK') RETURNING ID_PERSON INTO ?
and declaring an autput parameter for the statement
There's no standard way to do it (just as there is no standard way to create auto-incrementing IDs). Here are two ways to do it in PostgreSQL. Assume this is your table:
CREATE TABLE mytable (
id SERIAL PRIMARY KEY,
lastname VARCHAR NOT NULL,
firstname VARCHAR
);
You can do it in two statements as long as they're consecutive statements in the same connection (this will be safe in PHP with connection pooling because PHP doesn't give the connection back to the pool until your script is done):
INSERT INTO mytable (lastname, firstname) VALUES ('Washington', 'George');
SELECT lastval();
lastval() gives you the last auto-generated sequence value used in the current connection.
The other way is to use PostgreSQL's RETURNING clause on the INSERT statement:
INSERT INTO mytable (lastname) VALUES ('Cher') RETURNING id;
This form returns a result set just like a SELECT statement, and is also handy for returning any kind of calculated default value.
An important note is that using vendor SQL queries to retrieve the last inserted ID are safe to use without fearing about concurrent connections.
I always thought that you had to create a transaction in order to INSERT a line and then SELECT the last inserted ID in order to avoid retrieving an ID inserted by another client.
But these vendor specific queries always retrieve the last inserted ID for the current connection to the database. It means that the last inserted ID cannot be affected by other client insertions as long as they use their own database connection.
For SQL 2005:
Assuming the following table definition:
CREATE TABLE [dbo].[Test](
[ID] [int] IDENTITY(1,1) NOT NULL,
[somevalue] [nchar](10) NULL,
)
You can use the following:
INSERT INTO Test(somevalue)
OUTPUT INSERTED.ID
VALUES('asdfasdf')
Which will return the value of the ID column.
From the site i found out the following things:
SQL SERVER – ##IDENTITY vs SCOPE_IDENTITY() vs IDENT_CURRENT – Retrieve Last Inserted Identity of Record
March 25, 2007 by pinaldave
SELECT ##IDENTITY
It returns the last IDENTITY value produced on a connection, regardless of the table that produced the value, and regardless of the scope of the statement that produced the value.
##IDENTITY will return the last identity value entered into a table in your current session. While ##IDENTITY is limited to the current session, it is not limited to the current scope. If you have a trigger on a table that causes an identity to be created in another table, you will get the identity that was created last, even if it was the trigger that created it.
SELECT SCOPE_IDENTITY()
It returns the last IDENTITY value produced on a connection and by a statement in the same scope, regardless of the table that produced the value.
SCOPE_IDENTITY(), like ##IDENTITY, will return the last identity value created in the current session, but it will also limit it to your current scope as well. In other words, it will return the last identity value that you explicitly created, rather than any identity that was created by a trigger or a user defined function.
SELECT IDENT_CURRENT(‘tablename’)
It returns the last IDENTITY value produced in a table, regardless of the connection that created the value, and regardless of the scope of the statement that produced the value.
IDENT_CURRENT is not limited by scope and session; it is limited to a specified table. IDENT_CURRENT returns the identity value generated for a specific table in any session and any scope.
Remember that ##IDENTITY returns the most recently created identity for your current connection, not necessarily the identity for the recently added row in a table. You should always use SCOPE_IDENTITY() to return the identity of the recently added row.
What database are you using? As far as I'm aware, there is no database agnostic method for doing this.
This is how I've done it using parameterized commands.
MSSQL
INSERT INTO MyTable (Field1, Field2) VALUES (#Value1, #Value2);
SELECT SCOPE_IDENTITY();
MySQL
INSERT INTO MyTable (Field1, Field2) VALUES (?Value1, ?Value2);
SELECT LAST_INSERT_ID();
sql = "INSERT INTO MyTable (Name) VALUES (#Name);" +
"SELECT CAST(scope_identity() AS int)";
SqlCommand cmd = new SqlCommand(sql, conn);
int newId = (int)cmd.ExecuteScalar();
Ms SQL Server: this is good solution even if you inserting more rows:
Declare #tblInsertedId table (Id int not null)
INSERT INTO Test ([Title], [Text])
OUTPUT inserted.Id INTO #tblInsertedId (Id)
SELECT [Title], [Text] FROM AnotherTable
select Id from #tblInsertedId
Rob's answer would be the most vendor-agnostic, but if you're using MySQL the safer and correct choise would be the built-in LAST_INSERT_ID() function.
SELECT ##Scope_Identity as Id
There is also ##identity, but if you have a trigger, it will return the results of something that happened during the trigger, where scope_identity respects your scope.
insert the row with a known guid.
fetch the autoId-field with this guid.
This should work with any kind of database.
An Environment Based Oracle Solution:
CREATE OR REPLACE PACKAGE LAST
AS
ID NUMBER;
FUNCTION IDENT RETURN NUMBER;
END;
/
CREATE OR REPLACE PACKAGE BODY LAST
AS
FUNCTION IDENT RETURN NUMBER IS
BEGIN
RETURN ID;
END;
END;
/
CREATE TABLE Test (
TestID INTEGER ,
Field1 int,
Field2 int
)
CREATE SEQUENCE Test_seq
/
CREATE OR REPLACE TRIGGER Test_itrig
BEFORE INSERT ON Test
FOR EACH ROW
DECLARE
seq_val number;
BEGIN
IF :new.TestID IS NULL THEN
SELECT Test_seq.nextval INTO seq_val FROM DUAL;
:new.TestID := seq_val;
Last.ID := seq_val;
END IF;
END;
/
To get next identity value:
SELECT LAST.IDENT FROM DUAL
In TransactSQL, you can use OUTPUT clause to achieve that.
INSERT INTO my_table(col1,col2,col3) OUTPUT INSERTED.id VALUES('col1Value','col2Value','col3Value')
FRI: http://msdn.microsoft.com/en-us/library/ms177564.aspx
Simplest answer:
command.ExecuteScalar()
by default returns the first column
Return Value
Type: System.Object
The first column of the first row in the result set, or a null reference (Nothing in Visual Basic) if the result set is empty. Returns a maximum of 2033 characters.
Copied from MSDN
In SQL Server 2005 I have an "id" field in a table that has the "Is Identity" property set to 'Yes'. So, when an Insert is executed on that table the "id" gets set automatically to the next incrementing integer. Is there an easy way when the Insert is executed to get what the "id" was set to without having to do a Select statement right after the Insert?
duplicate of:
Best way to get identity of inserted row?
In .Net at least, you can send multiple queries to the server in one go. I do this in my app:
command.CommandText = "INSERT INTO [Employee] (Name) VALUES (#Name); SELECT SCOPE_IDENTITY()";
int id = (int)command.ExecuteScalar();
Works like a charm.
If you're inserting multiple rows, the use of the OUTPUT and INSERTED.columnname clause on the insert statement is a simple way of getting all the ids into a temp table.
DECLARE #MyTableVar table( ID int,
Name varchar(50),
ModifiedDate datetime);
INSERT MyTable
OUTPUT INSERTED.ID, INSERTED.Name, INSERTED.ModifiedDate INTO #MyTableVar
SELECT someName, GetDate() from SomeTable
Scope_identity() is the preferred way, see: 6 Different Ways To Get The Current Identity Value
SCOPE_IDENTITY(); is your best bet. And if you are using .NET just pass an our parameter and check the value after the procedure is run.
CREATE PROCEDURE [dbo].[InsertProducts]
#id INT = NULL OUT,
#name VARCHAR(150) = NULL,
#desc VARCHAR(250) = NULL
AS
INSERT INTO dbo.Products
(Name,
Description)
VALUES
(#name,
#desc)
SET #id = SCOPE_IDENTITY();
You have to select the scope_identity() function.
To do this from application code, I normally encapsulate this process in a stored procedure so it still looks like one query to my application.
I tend to prefer attaching a trigger to the table using enterprise manager. That way you don't need to worry about writing out extra sql statements in your code. Mine look something like this:
Create Trigger tblName
On dbo.tblName
For Insert
As
select new_id = ##IDENTITY
Then, from within your code, treat your insert statements like select statements- Just execute and evaluate the results. the "newID" column will contain the identity of the row you just created.
This is probably the best working solution I found for SQL Server..
Sql Server return the value of identity column after insert statement