How do I set a value in a variable column name? For some context, I am writing a function to be used as a trigger which sets a variable column to a constant value. To be used as follows:
CREATE TRIGGER always_6_trigger
BEFORE INSERT
ON table
FOR EACH ROW
EXECUTE PROCEDURE always_6('col1');
The above would result in the following rows all having a col1
value of 6. So for example:
INSERT INTO table (col1, col2) VALUES (6, 2), (null, 9), (null, 10), (7, 2);
Would result in:
| col1 | col2 |
---------------
| 6 | 2 |
| 6 | 9 |
| 6 | 10 |
| 6 | 2 |
Or if using the following trigger:
CREATE TRIGGER always_6_trigger
BEFORE INSERT
ON table
FOR EACH ROW
EXECUTE PROCEDURE always_6('col2');
And the same insert:
INSERT INTO table (col1, col2) VALUES (6, 2), (null, 9), (null, 10), (7, 2);
The table would look like:
| col1 | col2 |
---------------
| 6 | 6 |
| null | 6 |
| null | 6 |
| 7 | 6 |
How would I write the always_6
function?
Edit: To better explain the use case, the constant value would be current_setting('user_id')
(or something alike). And the column name would be things like author_id
and user_id
. The thinking being that a user could never add for data which was not their own.
You can define your function to produce dynamically generated SQL .
The EXECUTE command takes a string as input and executes it as SQL, so it would look something like this:
EXECUTE FORMAT('UPDATE mytable SET %I='constantvalue' WHERE condition', colname);
Here I have used the FORMAT function to prepare a string with the value of colname
substituted in where the column name would go. condition
would be some valid WHERE clauses to select the record to update.
If the value of colname
could come from an external source (ie. user supplied data) then you would have to be very careful to validate it beforehand, otherwise you might create an SQL injection vector.
您可以使用动态查询来执行此操作,并将传递的参数值条件检查到存储过程的输入参数。
I think I oversimplified the task based on the initial description, but would something like this work? You can't pass a parameter to a trigger function, but you mentioned the parameter was the result of another function current_setting('user_id')
, so is it possible to roll the two concepts together like this?
CREATE OR REPLACE FUNCTION always_6()
RETURNS trigger AS
$BODY$
DECLARE
current_user_id varchar;
BEGIN
current_user_id := current_setting('user_id');
if current_user_id = 'test1' then
new.col_1 := 6;
elsif current_user_id = 'test2' then
new.col_2 := 6;
end if;
return NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.