Zend 2 + Postgresql views - getGeneratedValue() - postgresql

I'm using views in Postgresql and I encounter a problem in Zend: I can't retrieve the last inserted value of an insert request.
Example:
I have an user_view and when I insert in, it does instead:
INSERT INTO basic_user(name, email) VALUES [...]; INSERT INTO extended_user(id, phone) VALUES (lastval(), [...]);
When I execute the request in Zend and call getGeneratedValue() it returns NULL...
How can I get the lastval() ?
I tried to use the RETURNING clause in my INSERT but without success..
Thx for your help.

The solution in PGSQL is currval(Sequence name) PG Doc.
Example
INSERT INTO basic_user(name, email) VALUES [...]; INSERT INTO extended_user(id, phone) VALUES (currval(basic_user_seq)(), [...]);

Related

Dapper issue with postgres returning id or select currval(pg_get_serial_sequence('<table>','<id>'))?

I'm trying to use Dapper, Npgsql to connect to a postgres database from a .net application. After an insert, I want to know the id of inserted row. I have read and tried options discussed here.
I have tried using returning id like so:
id = connection.Execute("insert into document_tag (tag) values (#tag) returning id;",
new { tag },
transaction);
but I get only '1' in id.
I also tried to use currval like so:
id = connection.Execute("insert into document_tag (tag) values (#tag); select currval(pg_get_serial_sequence('document_tag','id'));",
new { tag },
transaction);
Even in this case, I get only '1' in id.
In both cases, the insert was successful and the id column in the database had a valid serial number other than '1'.
Is my expectation wrong or is there an alternative?
To insert a row and get back a database-generated column, use:
INSERT INTO document_tag (tag) VALUES (#tag) RETURNING id
Note that there is no semicolon before "RETURNING" - it's just a clause of the INSERT statement, as you can see in the PostgreSQL docs.
In addition, once you add a RETURNING clause, the INSERT statement returns a resultset containing the requested information, just as if you executed a SELECT statement. Dapper's Execute() is meant to execution without resultsets, so you will need to switch to Query(), and probably add a Single() method to extract the single value you need. An alternative would be ExecuteScalar().
As suggested by #Shay: using connection.QueryFirst<int> instead of connection.Exeucte and got it working. Updated working code:
id = connection.QueryFirst<int>("insert into document_tag (tag) values (#tag) returning id;",
new { tag },
transaction);

I need to temporarily "store" info, or put a query in a query and do an insert into SQL Server 2005

So I have 2 tables that I need to insert similar data into. They are employee DBs that different applications access. They are:
dbo_Employees
dbo_EmpDefaultSchedules
dbo_EmpUsers
dbo_EmpDefaultLocation
So on dbo_Employees, when you insert a row, the primary key is auto-created. That column is called EmpID. There are a total of around 22 different columns being added to these different tables. They are things like FirstName, LastName, Address, Phone, etc., etc.
I'm trying to create a script where I can take a list of variables, enter them in once, and run that script to add it to the 4 tables at once (eventually a web page that HR will enter the info and create it themselves)
The only one that is giving me trouble is dbo_EmpDefaultSchedules. This is because I need the primary key from dbo_Employees (EmpID) to insert into dbo_EmpDefaultSchedules, and obviously it's not created until the first part of the script runs. My insert statement for the second part is this:
INSERT INTO [Database].[dbo].[EmpDefaultSchedules] (StaffCode, EmpID, LastName, FirstName, Dept, MgrStaffCode, IsMgr, PayrollStatus, PayFrequency, StdHrsWk, EmailAddress )
VALUES (#StaffCode, (select EmpID from [Database].[dbo].[Employees] WHERE StaffCode = #StaffCode), #LastName, #FirstName, #Dept, #MgrStaffCode, #IsMgr, #PayrollStatus, #PayrollFrequency, #StdHrsWk, #EmailAddress)
When I do this I get this error:
Subqueries are not allowed in this context. Only scalar expressions
are allowed.
I have seen/read this:
Subqueries are not allowed in this context. Only scalar expressions are allowed
And this:
MYSQL inserting into multiple tables
And this:
How do I store a value from a sql query into a variable?
And this:
How do I combine a SELECT + WHERE query with an INSERT query?
But still cannot get this to work.
You retrieve the identity to a variable using SCOPE_IDENTITY just after you insert into employees
SCOPE_IDENTITY (Transact-SQL)
What you can do is the following.
insert into Employees values (x,y,z)
insert into EmpDefaultSchedules (#staffcode, ##identity,....)
The ##identity is filled with the inserted EmpID, which you can use later on. If you insert another record after the Employees, and before the EmpDefaultschedules, make sure you put the ##identity in a variable
declare #EmpId int
insert into Employees values (x,y,z)
set #EmpId = ##identity
insert into EmpDefaultSchedules (#staffcode, #EmpId,....)

firebird insert into returning into another insert

I'm using Firebird as DB and I need to do this:
INSERT INTO TG (ID, UID, GID)
SELECT (INSERT INTO TBO VALUES (GEN_ID('o',1)) RETURNING ID), UID, 10
FROM TBL l
WHERE l.is=1
the part with select is OK when I use:
SELECT (GEN_ID('o',1)), UID, 10
FROM TBL l
WHERE l.is=1
but I need the ID in other table for dependency first.
I know about something called procedures but I have no idea how to use them. Is there an option to do this using SQL?
Take a look at EXECUTE BLOCK statement. It allow you to execute multiple statements in one "batch" or write complex logic if you cannot embed it in one SQL query.
Inside EXECUTE BLOCK you can write mutiple commands using PSQL.
EB allow input params, output params (yes you can use it as a table), local variables, if statement, while, for select etc... very powerfull tool.
Just prepare your block and execute it like simple SQL query.
A simpler aproach would be to use triggers.
In this example it would be a before insert trigger.
Something like this:
CREATE TRIGGER TG_BI0 FOR TABLE TG ACTIVE BEFORE INSERT 0
AS
BEGIN
/* Before insert create a new record in TBO */
INSERT INTO TBO (ID) VALUES (NEW.ID);
END
After having this trigger you shloud only insert records in TG.
INSERT INTO TG (ID, UID, GID)
VALUES (GEN_ID('o',1), 'SOME_UUID', 10)

Multiple Insert statement failing ORA-00905: missing keyword error

I am using the below SQL script to insert few records into a new table that I created using create statement. But I am getting the following error
ORA-00905: missing keyword
Below is the script which is quite straightforward. I guess I am missing something. FYI, I have tested with both ; at the end and without ; but it yields the same result.
Any idea what I am missing here?
create table winlossbydate1 (
statusdate Date,
Status Char(5));
Insert into WinLossByDate (StatusDate, Status)
Values (TO_DATE('2011-03-01','yyyy-mm-dd'), 'win');
Insert into WinLossByDate (StatusDate, Status)
Values (TO_DATE('2011-03-01','yyyy-mm-dd'), 'lose');
Insert into WinLossByDate (StatusDate, Status)
Values (TO_DATE('2011-03-01','yyyy-mm-dd'), 'lose');
Insert into WinLossByDate (StatusDate, Status)
Values (TO_DATE('2011-03-01','yyyy-mm-dd'), 'lose');
Insert into WinLossByDate (StatusDate, Status)
Values (TO_DATE('2011-03-01','yyyy-mm-dd'), 'win');
Insert into WinLossByDate (StatusDate, Status)
Values (TO_DATE('2011-03-02','yyyy-mm-dd'), 'lose');
Insert into WinLossByDate (StatusDate, Status)
Values (TO_DATE('2011-03-02','yyyy-mm-dd'), 'win');
Insert into WinLossByDate (StatusDate, Status)
Values (TO_DATE('2011-03-02','yyyy-mm-dd'), 'win');
Insert into WinLossByDate (StatusDate, Status)
Values (TO_DATE('2011-03-02','yyyy-mm-dd'), 'win')
If with SQL command tool of Oracle 10g XE you mean the browser based HTML UI that comes with XE, then that's your problem.
The XE browser frontend simply does not support running multiple SQL statements.
You might consider using SQL Developer or any other "real" GUI tool instead.

Postgresql Stored Procedures: Using id from one statement in another

Is it possible to create a stored procedure with two insert statements where id/primary_key from the first insert statement will be used in second.
For eg.
INSERT INTO activity VALUES (DEFAULT, 'text', 'this is a test');
If the id returned from the above statement is x, the second insert will be like:
INSERT INTO activity_tree VALUES (DEFAULT, **x**, user_id) or something like that.
I understand thatlibpq has functions which can give the id from the first statement.
But I want to combine them into a stored procedure. Please advise.
Regards,
Mayank
Declare a variable, e.g. new_id and then you can store the generate id in there:
INSERT INTO activity VALUES (DEFAULT, 'text', 'this is a test')
RETURNING id INTO new_id;
INSERT INTO activity_tree VALUES (DEFAULT, new_id, user_id);
This assumes the column where the value is generated is called id
Btw: do not use "unqualified" insert statements. Always specify the columns in the INSERT part. That makes your code much more stable:
INSERT INTO activity (id, some_column, other_column)
VALUES
(DEFAULT, 'text', 'this is a test')
And make sure you are not calling variables the same way as columns. user_id seems to be a potential naming conflict here. This will compile with 8.x but might give you strange errors. I think this will no longer compile with 9.x