I would like to change the key value and also tried to create a test in SQLfiddle, but it did not work. The below output I have got from pgAdmin3:
Select * from api_keys;
id, create_time, user_id, key
1;"2015-11-17 01:23:08.872941";1;"d0dff17e3753a88d298ae775bb32eee6"
How is it possible to change the key value in api_keys?
You mean UPDATE?
To change all rows with key = 'd0dff17e3753a88d298ae775bb32eee6':
UPDATE api_keys
SET key = 'd0dff17e3753a88d298ae775bb32eee7'
WHERE key = 'd0dff17e3753a88d298ae775bb32eee6';
Related
Question
Imagine having the following PostgreSQL table:
CREATE TABLE setting (
user_id bigint PRIMARY KEY NOT NULL,
language lang NOT NULL DEFAULT 'english',
foo bool NOT NULL DEFAULT true,
bar bool NOT NULL DEFAULT true
);
From my research, I know to INSERT a row with the default values if the row for the specific user did not exist, would look something like this:
INSERT INTO setting (user_id)
SELECT %s
WHERE NOT EXISTS (SELECT 1 FROM setting WHERE user_id = %s)
(where the %s are placeholders where I would provide the User's ID)
I also know to get the user's setting (aka to SELECT) I can do the following:
SELECT * FROM setting WHERE user_id = %s
However, I am trying to combine the two, where I can retrieve the user's setting, and if the setting for the particular user does not exist yet, INSERT default values and return those values.
Example
So it would look something like this:
Imagine Alice has her setting already saved in the database but Bob is a new user and does not have it.
When we execute the magical SQL query with Alice's user ID, it will return Alice's setting stored in the database. If we execute the same identical magical SQL query on Bob's user ID, it will detect that Bob does not have any setting saved in the database , thus it will INSERT a setting record with all default values, and then return Bob's newly created setting.
Given that there is an UNIQUE or PK constraint on user_id as Frank Heikens said then try to insert, if it violates the constraint do nothing and return the inserted row (if any) in the t CTE, union it with a 'proper' select and pick the first row only. The optimizer will take care than no extra select is done if the insert returns a row.
with t as
(
insert into setting (user_id) values (%s)
on conflict do nothing
returning *
)
select * from t
union all
select * from setting where user_id = %s
limit 1;
No magic necessary. Use returning and union all:
with inparms as ( -- Put your input parameters in CTE so you bind only once
select %s::bigint as user_id
), cond_insert as ( -- Insert the record if not exists, returning *
insert into settings (user_id)
select i.user_id
from inparms i
where not exists (select 1 from settings where user_id = i.user_id)
returning *
)
select * -- If a record was inserted, get it
from cond_insert
union all
select s.* -- If not, then get the pre-existing record
from inparms i
join settings s on s.user_id = i.user_id;
Say I have a table like below with values I want to update in specific rows, but no primary key, I only know the index of the row I want to update. Is this possible with generic SQL or would I need some DB specific tools? I'm using Postgres and SQLite. I realise this is bad DB design and the obvious solution is to simply add an id primary key to the table, but my use case is the DB is the backend for a flexible Excel-like application, where I have no control over the table schema, as it is user defined.
CREATE TABLE fruits (name TEXT);
INSERT INTO fruits VALUES (banana) (aple) (orange);
To fix the typo, I want to do something like:
UPDATE fruits SET name = 'apple' WHERE *row index* = 1;
Note I'm using 0-indexing in this pseudo code example.
Did you try
UPDATE fruits SET name='<new_name>' WHERE rowid=3 ?
rowid docs
You could try
UPDATE fruits SET name = 'apple' WHERE name =(
SELECT name FROM
(SELECT name, row_number() over (order by name) as line_number FROM fruits )
A
WHERE line_number = 1
)
So ROW_NUMBER is dynamically creating a unique number for each name, but it is doing so by sorting the results by name. So the index will be 1 if you want to select the 'Aple' entry.
I am writing a SQL statement to update a table in SQL from a temp table. I keep getting this error message: Cannot insert duplicate key row in object with unique index 'SAXXIRPT'.
Here is my update statement:
Update dbo.sat_ser_rpt_itm
SET itm_key_cd = n.itm_key_cd,
itm_typ_cd = n.itm_typ_cd,
ser_id = n.ser_id ,
as_of_dt = n.as_of_dt,
ocrn_nr = n.ocrn_nr ,
id_rssd = n.id_rssd,
ocrn_day_txt = n.ocrn_day_txt ,
ocrn_dt = n.ocrn_dt ,
hol_flg = n.hol_flg ,
ocrn_val_nr = n.ocrn_val_nr
from #LookupTable n
on sat_ser_rpt_itm.id_rssd = n.id_rssd
AND sat_ser_rpt_itm.as_of_dt = n.as_of_dt
AND sat_ser_rpt_itm.ser_id = n.ser_id
and sat_ser_rpt_itm.itm_typ_cd = n.itm_typ_cd
and sat_ser_rpt_itm.ocrn_nr = n.ocrn_nr
where t.id_rssd is not null and t.as_of_dt is not null and t.ser_id is not null and t.itm_typ_cd is not null and t.ocrn_nr is not null
These are my indexes (clustered):
id_rssd, as_of_dt, ser_id, itm_key_cd and ocrn_nr
What's causing this error message?
There isn't much ambiguity in the error message: you are setting a duplicate somewhere
The combination already exists and you are trying to insert it again OR
It doesn't exist and you are updating multiple rows with the same
combination Or
the overlap: The combination already exists and you
are updating multiple rows with the same combination.
I think the problem causing you this Updating multiple rows with same combination
I am not sure about the what is primary key for the table dbo.sat_ser_rpt_itm
Try like this by joining two tables (dbo.sat_ser_rpt_itm,#lookup_table)
Update itm
SET
//itm_key_cd = n.itm_key_cd,
//ser_id = n.ser_id
itm_typ_cd = n.itm_typ_cd,
//as_of_dt = n.as_of_dt,
//ocrn_nr = n.ocrn_nr ,
//id_rssd = n.id_rssd,
ocrn_day_txt = n.ocrn_day_txt ,
ocrn_dt = n.ocrn_dt ,
hol_flg = n.hol_flg ,
ocrn_val_nr = n.ocrn_val_nr
FROM dbo.sat_ser_rpt_itm itm
INNER JOIN #LookupTable n
ON .................. ( it could be itm.id_rssd = n.id_rssd OR itm.as_of_dt = n.as_of_dt OR
OR itm.ser_id = n.ser_id OR itm.itm_key_cd = n.itm_key_cd OR
itm.ocrn_nr = n.ocrn_nr )
WHERE t.id_rssd is not null AND t.as_of_dt is not null
AND t.ser_id is not null AND t.itm_typ_cd is not null AND t.ocrn_nr is not null
Quite late to answer but your problem is probably simple and your key constraint (you don't show that but that's likely your issue) is doing exactly what it should be doing.
When you combine your update statement data into the constrained key, were you to do a select by that key you would find that you return a single result. The solution is to select by the key first and see if it exists and either update that if desired, xor delete the duplicate, or do something else.
so look at the key constraint which is being violated--the message should say 'duplicate key is (something,etc...) Select by that and see if you are not trying to change an existing item into another existing item.
Cheers,
Daniel Westcott
Okay I have two tables
VOUCHERT with the following fields
ACTIVATIONCODE
SERIALNUMBER
VOUCHERDATADBID
UNAVAILABLEAT
UNAVAILABLEOPERATORDBID
AVAILABLEAT
AVAILABLEOPERATORDBID
ACTIVATIONCODENEW
EXT1
EXT2
EXT3
DENOMINATION -- I added this column into the table.
and the second table is VOUCHERDATAT with the following fields
VOUCHERDATADBID
BATCHID
VALUE
CURRENCY
VOUCHERGROUP
EXPIRYDATE
AGENT
EXT1
EXT2
EXT3
What I want to do is copy the corresponding VALUE from VOUCHERDATAT and put it into DENOMINATION of VOUCHERT. The linking between the two is VOUCHERDATADBID. How do I go about it?
It is not a 1:1 mapping. What I mean is there may be 1000 SERIALNUMBERS with a same VOUCHERDATADBID. And that VOUCHERDATADBID has only entry in VOUCHERDATAT, hence one value. Therefore, all serial numbers belonging to a certain VOUCHERDATADBID will have the same value.
Will JOINS work? What type of JOIN should I use? Or is UPDATE table the way to go?
Thanks for the help !!
Your problem is one of design. None of your tables are in any of the normal forms, not even in the first normal form (1NF). You should not add a column to the VOUCHERT table, but create a new table (pick the name) with the following columns: SERIALNUMBER, VALUE, VOUCHERDATADBID (maybe ACTIVATIONCODE too - need to know the primary key on VOUCHERT to be sure if ACTIVATIONCODE should be included in the new table). Normalization is the database design process that aims to resolve any possible INSERT/UPDATE/DELETE anomalies. This should solve your INSERT issue.
Hope this helps.
You can do a join between these two tables and you will get a 'view'. You can update this view like:
UPDATE (SELECT *
FROM VOUCHERT A JOIN VOUCHERDATAT B
ON A.VOUCHERDATADBID = B.VOUCHERDATADBID)
SET DENOMINATION = VALUE;
You may put outer join if you need.
VOUCHERDATADBID MUST BE PRIMARY KEY in VOUCHERDATAT and FOREIGN KEY in VOUCHERT, otherwise you will get an error:
ORA-01779: cannot modify a column which maps to a non key-preserved table
update (
select v.DENOMINATION
, vd.VALUE
from VOUCHERT v
join VOUCHERDATAT vd
on vd.VOUCHERDATADBID = v.VOUCHERDATADBID
) t
set t.DENOMINATION = t.Value
If the voucherdatadbid is not a primary key, this should work:
UPDATE vouchert
SET denomination =
(SELECT MAX(value)
FROM voucherdatat
WHERE voucherdatadbid = vouchert.voucherdatadbid);
I have a table as A (code,id,num,address)
Here code, id, and num are primary keys and no Foreign key dependency is present on any other table.
I need to update num using id… can I do that?
num was telephone number.i figurd this out.but i have another question
can we update the same column num using num only.example
UPDATE A
SET num = ''
WHERE num = '';
You could try something like this:
update A
set num = $someValue
where id = $someOtherValue;
You say there are no foreign keys that rely on this key so why not?
UPDATE A
SET num = '<value>'
WHERE id = '<identifier>';
Should suffice, if I understand your question correctly.
Given that the primary key will still be unique after the update and given that you did not define something like "alway generated" for this column: Yes, you can.