How can use PostgreSQL array_append() and array_remove() in Yii? I am trying to update array type attribute on following table rows-
CREATE TABLE Books(
id INT NOT NULL PRIMARY KEY,
name UUID[])
Sample data rows:
1 NULL
2 NULL
$books=Books::model()->findByPk($id);
$books->name='array_append(name, $Name_key_array)';
$books->save();
I have found following error:
CDbException
CDbCommand failed to execute the SQL statement: SQLSTATE[22P02]: Invalid text representation: 7 ERROR: array value must start with "{" or dimension information
But If I use array directly then its work but not when using variable name i.e.
array_append({1,2,3}, {4})
Also, I already tried few more ways but haven't found any success. I hope will find some great ideas to fix this issue.
I think you are using the array_append() in other way. it should be like this
SELECT array_append(ARRAY[1,2], 3);
array_append
--------------
{1,2,3}
(1 row)
So if i correct yours, it should be
$books->name='array_append($Name_key_array, name)';
for removing elements from an array, check this solution: http://www.youlikeprogramming.com/2013/06/removing-values-from-a-postgresql-array/
to an array in PostgreSQL data must be inserted in the following way,
INSERT INTO table (arr_col) VALUES ('{val1,val2, val3}');
http://www.postgresql.org/docs/9.1/static/arrays.html
Related
I have a table in Postgres with DDL like this one:
CREATE TABLE robots(
robot_id INTEGER NOT NULL CONSTRAINT robot_id_pkey PRIMARY KEY,
name TEXT
);
I know I can insert a record with following SQL statement:
INSERT INTO robots (robot_id, name) VALUES (nextval('robots_seq'), 'WALL-E');
I need to make CRUD operations in Phalcon for this table. Also I want to use ORM features.
So I do:
$robot = new Robots();
$robot->setRobotId(new \Phalcon\Db\RawValue("nextval('robots_seq')"));
$robot->setName('WALL-E');
$robot->save();
And get the following exception:
Uncaught PDOException: SQLSTATE[22P02]: Invalid text representation:
7 ERROR: invalid input syntax for integer: 'nextval('robots_seq')';
Is there any way to accomplish this ?
To tell Phalcon what is name of your model sequence use function getSequenceName:
public function getSequenceName() {
return 'category_id_seq';
}
Phalcon assumes that your models with serial (auto increment) columns will have a sequence named [table_name]_[column_name]_seq.
In your case, in order to make Phalcon take care of handling auto increment columns you should have a sequence named robots_robot_id_seq instead of robots_seq for the column robot_id (which I'd call just "id", by the way).
This way you do not have to worry about setting the id when creating an object and after saving Phalcon will fill that field automatically for you:
CREATE TABLE robots(
robot_id SERIAL PRIMARY KEY NOT NULL,
name TEXT
);
$robot = new Robots();
$robot->setName('WALL-E');
$robot->save();
$robot->getRobotId(); // Should return last "nextval()" sequence
Hope it helps.
I'm trying to run an INSERT query into a table with 3 columns. The first column is where I'm having the issue.
It is called COMM_CODE with VARCHAR value of 10 length, and is the primary key, ALLOW NULL is unchecked.
The values for COMM_CODE look like this:
COMM_CODE
c20188
c20189
c20190
// and so on
What I would like to do, is when a new record is inserted, to basically add 1 to the most recent record.
Therefore, the most recent record is:
c20190
So when I add a new record, the COMM_CODE for the new record will be:
c20191
I tried this:
INSERT INTO table_c
(COMM_CODE, COMM_DESC, DATE)
VALUES
(''+1, 'VIDEO GAMES', NOW());
But that just adds a number 1 to that column.
How can I make this happen?
Here the solution for your query :
To generate the new code I'hv created get_new_code function in mysql. I hope you know how funcions work in mysql.
CREATE FUNCTION `get_new_code`() RETURNS varchar(11)
BEGIN
Declare var_code VARCHAR(11);
SELECT max(`COMM_CODE`) INTO var_code FROM table_c;
RETURN (CONCAT('c',(convert(substr(var_code,2,length(var_code)), SIGNED INTEGER)+1)));
END
Just to verify your logic you can use :
select get_new_code();
So that you will get the clear picture.
Call this get_new_code function in insert query like this :
INSERT INTO
`table_c`(`COMM_CODE`, `COMM_DESC`, `COMM_DATE`)
VALUES
(get_new_code(),'Description text',NOW());
This should solve your problem. :)
Using PHP 5.3.2 and Oracle 11G, I'm trying to pass an array from PHP into an oracle stored proc. Here is my PL/SQL:
create or replace type NUM_ARRAY as table of number;
create or replace package txa as
procedure upsert_txa_compliance_slct( v_compl_id_array in num_array);
end txa;
create or replace package body txa as
procedure upsert_txa_compliance_slct(v_compl_id_array in num_array)
is
begin
.
. -- sql code removed for brevity. package and body compile no errors
.
end upsert_txa_compliance_slct;
end;
The Query:
$sql = "begin txa.upsert_txa_compliance_slct(:my_array); end;";
And the PHP Code I've tried to bind the array and execute :
First:
<?
$this->conn = ociplogon($dbuser, $dbpass, $dbname);
$this->commit_mode = OCI_COMMIT_ON_SUCCESS;
$this->sth = #ociparse($this->conn, $sql);
oci_bind_array_by_name($this->sth,
':my_array',
$my_array,
count($my_array),
-1,
SQLT_CHR);
$r = #ociexecute($this->sth, $this->commit_mode);
?>
Which generates this error:
PLS-00306: wrong number or types of arguments in call to 'UPSERT_TXA_COMPLIANCE_SLCT'
I'm clearly passing 1 arg. So, what's wrong with/how do I fix the type issue?
Additionally I found this
http://www.oracle.com/technetwork/articles/seliverstov-multirows-098120.html
And tried it the old way using oci collection like so:
$collection = oci_new_collection($this->conn,"NUM_ARRAY");
After I changed my oracle type to this:
create or replace type NUM_ARRAY as varray(100) of number;
I got this error:
oci_new_collection(): ORA-22318: input type is not an array type
Any help would be MUCH appreciated.
EDIT 7:08PM ET Aug 14, 2014
I changed my php oci_bind function call to use SQLT_NUM as the type. This had no impact. Then I changed my package to include:
type num_array is table of number index by binary_integer;
( i also dropped the original num_array from my schema )
This change made it possible to pass my array to the stored proc, but then I can't use the array as a nested table like so:
delete
from my_table
where id not in (select column_value from table(v_compl_id_array));
I get this error when i try to compile the package body with that statement in it:
PL/SQL: ORA-22905: cannot access rows from a non-nested table item
And all the documentation tells me to return to the schema level type? But when I do I get that other error. I know I can find another way to do this using a loop over my pl/sql array, but I would really love to be able to use that schema level type.
The answer is this. You can't use a globally created or schema level type as a parameter to a stored procedure. PHP's oci_bind_array_by_name just doesn't seem to work with globally created types, but you need the globally created type to be able to use your array as a nested table in subselects. So.... here is how I got this to work. I'm MORE THAN HAPPY TO HEAR OTHER SOLUTIONS!! but for now, here's what I did.
-- globally create a type table of number
create or replace type num_array is table of number;
-- in my package i created an internal type table of number
type i_num_array is table of number index by binary_integer;
-- i then used i_num_array (internal type) as the type for my IN parameter to the procedure
upsert_TXA_compliance_slct( v_compl_id_array in i_num_array)
-- in my procedure i also created a variable that is the type of my globally created type
v_num_array num_array := num_array();
-- then i populated that variable in a loop inside my procedure with the values in my IN param
for i in 1 .. v_compl_id_array.count
loop
v_num_array.extend(1);
v_num_array(i) := v_compl_id_array(i);
end loop;
-- then i used v_num_array as my nested table so this now works:
delete from my_table where id in (select * from table(v_num_array));
I have a custom type
CREATE TYPE mytype as (id uuid, amount numeric(13,4));
I want to pass it to a function with the following signature:
CREATE FUNCTION myschema.myfunction(id uuid, mytypes mytype[])
RETURNS BOOLEAN AS...
How can I call this in postgres query and inevitably from PHP?
You can use the alternative syntax with a array literal instead of the array constructor, which is a Postgres function-like construct and may cause trouble when you need to pass values - like in a prepared statement:
SELECT myschema.myfunc('0d6311cc-0d74-4a32-8cf9-87835651e1ee'
, '{"(0d6311cc-0d74-4a32-8cf9-87835651e1ee, 25)"
, "(6449fb3b-844e-440e-8973-31eb6bbefc81, 10)"}'::mytype[]);
I added a line break between the two row types in the array for display. That's legal.
How to find the correct syntax for any literal?
Just ask Postgres. Here is a demo:
CREATE TABLE mytype (id uuid, amount numeric(13,4));
INSERT INTO mytype VALUES
('0d6311cc-0d74-4a32-8cf9-87835651e1ee', 25)
,('6449fb3b-844e-440e-8973-31eb6bbefc81', 10);
SELECT ARRAY(SELECT m FROM mytype m);
Returns:
{"(0d6311cc-0d74-4a32-8cf9-87835651e1ee,25.0000)","(6449fb3b-844e-440e-8973-31eb6bbefc81,10.0000)"}
db<>fiddle here
Any table (including temporary tables) implicitly creates a row type of the same name.
select myschema.myfunc('0d6311cc-0d74-4a32-8cf9-87835651e1ee'
, ARRAY[('ac747f0e-93d4-43a9-bc5b-09df06593239', '25.00')
, ('6449fb3b-844e-440e-8973-31eb6bbefc81', '10.00')]::mytype[]
);
Still need PHP portion of this resolved though, still not sure how to call a function populating with the custom array parameter.
I have an Oracle stored proc that takes 2 parameters. userid as an input parameter and an Oracle table with 2 columns as second out parameter. How can I invoke the procedure from PHP? I think that the problem stands in the oci_bind_* for the second parameter. I've tried oci_bind_array_by_name but I always get PLS-00306: wrong number or types of arguments in call to GET_VALUES.
Can anyone help me, please?
Here is my code:
$tab=array();
$query = "begin GET_VALUES(:P_CUSTOMERCODE,:P_TAB); end;";
$stmt = oci_parse($ora_conn, $query) or die(oci_error());
oci_bind_by_name($stmt,":P_CUSTOMERCODE",$codUtente,255);
oci_bind_array_by_name($stmt,":P_TAB",$tab,100,100,SQLT_CHR);
oci_execute($stmt) or die(oci_error());
This might answer your problem: How to call package from php having procedure in oracle using oci drivers?
Not sure a multi-column table will work with oci_bind_array_by_name. Looking at the php manual, you can use this to bind a simple varray, assoc array or nested table, basically as simply 1 column list of values. You'd specify the type of array in the "type" param, using SQLT_CHR for varchar2 for example (if you defined an array like : type t_array is table of varchar2(100) index by pls_integer).
Seems you created a custom table of a custom record type(?), something like:
type t_rec is record (
col1 number,
col2 varchar2(100)
);
type t_tab is table of t_rec;
I don't see where you can bind to t_tab as an out param using php's oci8 calls, but I may be mistaken.