A PostgreSQL trigger fires on UPDATE not on INSERT - ruby-on-rails

I have this recommendations table:
Table "public.recommendations"
Column | Type | Modifiers
-----------------------+-----------------------------+--------------------------------------------------------------
id | integer | not null default nextval('recommendations_id_seq'::regclass)
comment_on_provider | text |
created_at | timestamp without time zone | not null
updated_at | timestamp without time zone | not null
search_vector | tsvector |
Indexes:
"recommendations_pkey" PRIMARY KEY, btree (id)
"recommendations_search_vector_idx" gin (search_vector)
Triggers:
recommendations_vector_update BEFORE INSERT OR UPDATE ON recommendations FOR EACH ROW EXECUTE PROCEDURE search_trigger()
and this trigger
CREATE OR REPLACE FUNCTION search_trigger() RETURNS trigger AS $$
DECLARE
search TEXT;
links_title TEXT;
links_description TEXT;
begin
SELECT string_agg(title, ' ') INTO links_title
FROM links
INNER JOIN recommendations
ON new.link_id = links.id;
SELECT string_agg(description, ' ') INTO links_description
FROM links
INNER JOIN recommendations
ON new.link_id = links.id;
search := '';
search := search || ' ' || coalesce(new.comment_on_provider);
search := search || ' ' || links_title;
search := search || ' ' || links_description;
new.search_vector := to_tsvector(search);
return new;
end
$$ LANGUAGE plpgsql;
CREATE TRIGGER recommendations_vector_update
BEFORE INSERT OR UPDATE ON recommendations
FOR EACH ROW EXECUTE PROCEDURE
search_trigger();
When I insert a record to the recommendations table the trigger doesn't fire and search_vector is set to null.
But when I update any record it fires and search_vector gets updated with the expected values.
How to make the trigger working on INSERT?

I suppose in the case of INSERT some of the variables in the expressions assigned to the search variable are NULL. Most probably it's new.comment_on_provider but better check.

Related

How to remove quotes in sybase ASE

I have a string:
"16680,16678,16677,16676,16675,16672"
Which I got from the Stored procedure passed parameter while calling it. I want to insert these records in where in like
Where in (16680,16678,16677,16676,16675,16672).
How can I make this in Sybase ASE stored procedure?
You can use the str_replace() function to replace the double quotes with NULL, eg:
declare #strings varchar(15)
select #strings = '"1,2,3,4,5"'
select #strings, str_replace(#strings,'"',NULL)
go
--------------- ---------------
"1,2,3,4,5" 1,2,3,4,5
Feeding the new string into a query requires a bit more work though.
Trying to feed directly into a query generates an error, eg:
declare #strings varchar(15)
select #strings = '"1,2,3,4,5"'
select id from sysobjects where id in ( str_replace(#strings,'"',NULL) )
go
Msg 257, Level 16, State 1:
Server 'ASE400', Line 7:
Implicit conversion from datatype 'VARCHAR' to 'INT' is not allowed. Use the CONVERT function to run this query.
To get around this issue we can dynamically build the query and then run it via an execute() call, eg:
declare #strings varchar(15),
#query varchar(100)
select #strings = '"1,2,3,4,5"'
select #query = 'select id from sysobjects where id in (' || str_replace(#strings,'"',NULL) || ')'
print #query
execute (#query)
go
select id from sysobjects where id in (1,2,3,4,5)
id
-----------
1
2
3
4
5
Another solution that does away with the #query variable:
declare #strings varchar(15)
select #strings = '"1,2,3,4,5"'
select #strings = str_replace(#strings,'"',NULL)
execute( 'select id from sysobjects where id in (' || #strings || ')' )
go
id
-----------
1
2
3
4
5
NOTE: all code was run in an ASE 16.0 SP04 GA instance.

Calling a Sybase stored procedure from another stored procedure without displaying called stored procedure results

I am calling a Sybase stored procedure X from another stored procedure Y. Following the answer to a similar question , I create a #tmp_table to hold the results from stored procedure X.
create table #tmp_table(
col1 int,
col2 varchar(100),
...
) exec sp_stored_procedureX 888, 'Parameter2', ...
select * from #tmp_table
The above successfully loads stored procedure X's results into #tmp_table but it shows the results of stored procedure X twice. I guess the first one is from "exec sp_stored_procedureX ..." part and the second one is from "select * from #tmp_table" which I intended. I don't want to display the results from the first "exec sp_stored_procedureX ..." part. How can I store data to #tmp_table without displaying it?
Please kindly let me know if more clarification/information is needed.
Thanks & Regards,
Kyoto
your syntax is incorrect for normal table in ASE. But for ASE, there's a special table name RPC table can map the output of procedure to a table format output. Maybe that's what you are looking for...And that also can be called from remote ASE.
Here's a sample --
use omni_rpc
go
create table rmtbl
(
aint int null,
bchr char(10) null,
cchr char(10) null
)
go
insert rmtbl values (11, "b_row1", "c_row1")
insert rmtbl values (22, "b_row2", "c_row2")
insert rmtbl values (33, "b_row3", "c_row3")
insert rmtbl values (44, "b_row4", "c_row4")
insert rmtbl values (55, "b_row5", "c_row6")
go
create proc procImm #Colnames varchar(100), #NameT varchar(20), #nameCol varchar
(20), #value char(2)
as
execute ('select ' + #Colnames + ' from ' + #NameT + ' where '
+ #nameCol + ' = ' + #value)
Here #NameT and #Colnames are command parameters, and #value is a search parameter based on the terms defined at the beginning of the paper.
In the local server:
use test
go
sp_addobjectdef myrpc_imm, "THIS.omni_rpc..procImm", "rpc"
go
(return status = 0)
create existing table myrpc_imm
(
NameT varchar(20),
nameCol varchar(20),
value varchar(10)
)
external procedure at "THIS.omni_rpc..procImm"
go
select * from myrpc_imm
where NameT = 'rmtbl' and nameCol = 'aint' and value = '33'
go
NameT nameCol value
-------------------- -------------------- ----------
(0 rows affected)
dbcc traceon(11225)
go
00:00000:00017:2004/04/01 12:18:47.03 server DBCC TRACEON 11225, SPID 17
DBCC execution completed. If DBCC printed error messages, contact a user with
System Administrator (SA) role.
select * from myrpc_imm
where NameT = 'rmtbl' and nameCol = 'aint' and value = '33'
go
NameT nameCol value
-------------------- -------------------- ----------
33 b_row3 c_row3
(1 row affected)

Solve the syntax error with Redshift operator does not exist and add explicit casts

I am a newbie in the area of redshift data modeling and got myself into trouble with an error.ERROR:
--Final version
syntax error ERROR: operator does not exist: text | record Hint: No
operator matches the given name and argument type(s). You may need to
add explicit type casts. Where: SQL statement "SELECT 'create temp
table ' || $1 || ' as select * from' | $2 |" PL/pgSQL function "egen"
line 36 at execute statement [ErrorId:
1-61dc32bf-0a451f5e2c2639235abb8876]
I am trying to do a simple transformation that gets returned in output when the procedure is called. (As of now I got to find from the documentation we have to use either temp table or cursors to achieve this)
Pseudocode:
I am trying to restrict data to its latest one in (2019) Get the
list of managers create columns if a person is a manager or not from the list.
Return it as a result
Data looks as follows Employee Data
My Select query works fine out of the procedure, please find my complete code below.
CREATE OR REPLACE PROCEDURE EGEN(tmp_name INOUT varchar(256) )
AS $$
DECLARE
--As i have less data managed to create it as an array or please use temp or table and join it with the actual query to perform transformation
MGR_RECORD RECORD;
DATAS RECORD;
item_cnt int := 0;
V_DATE_YEAR int := 0;
BEGIN
--EXECUTE (select cast(extract(year from current_date) as integer)-3) INTO V_DATE_YEAR;
--Manager Records are stored here below
SELECT DISTINCT managerid from "dev"."public"."emp_salary" INTO MGR_RECORD;
SELECT employeeid,
managerid,
promotion,
q_bonus,
d_salary,
case when contractor = 'x'
then 'TemporaryEmployee'
else 'PermanentEmployee'
END as EmployeeType,
-- IFstatement not supported under select query
case when employeeid in (select distinct managerid FROM "dev"."public"."emp_salary" )
then 'Manager'
else 'Ordinary FTE'
END as FTETYPE
FROM "dev"."public"."emp_salary" where cast(extract(year from promotion) as int ) >= 2019 into DATAS;
--COMMIT;
tmp_name := 'ManagerUpdatedTable';
EXECUTE 'drop table if exists ' || tmp_name;
EXECUTE 'create temp table ' || 'ManagerUpdatedTable' || ' as select * from' |DATAS| ;
END;
$$ LANGUAGE plpgsql;
-- Call tests CALL EGEN('myresult'); SELECT * from myresult;
Also, additional query (Can we replace )
case when employeeid in (select distinct managerid FROM "dev"."public"."emp_salary" )
then 'Manager'
else 'Ordinary FTE'
END as FTETYPE
this transform in query to IF , if possible please provide details.
Thanks and Regards,
Gabby

Create dynamic SQL based on column names passed through a string

I need to find out rows that are present in table A and missing from table B (using LEFT JOIN) wherein table A and table B are two tables with same structure but within different schema.
But the query has to be constructed using Dynamic SQL and the columns that need to be used for performing JOIN are stored in a string. How to extract the column names from string and use them to dynamically construct below query :
Database is Azure SQL Server
eg :
DECLARE #ColNames NVARCHAR(150) = 'col1,col2'
Query to be constructed based on columns defined in ColNames :-
SELECT *
FROM Table A
Left Join
Table B
ON A.col1 = B.col1
AND A.col2 = B.col2
AND B.col1 IS NULL AND B.col2 IS NULL
If the number of columns in #ColNames is more then the SELECT statement needs to cater for all the column.
Without knowing the full context, try this:
DECLARE #ColNames NVARCHAR(150) = 'col1,col2'
DECLARE #JoinContion NVARCHAR(MAX) = ''
DECLARE #WhereCondition NVARCHAR(MAX) = ''
SELECT #JoinContion += CONCAT('[a].', QUOTENAME(Value), ' = ', '[b].', QUOTENAME(Value), (CASE WHEN LEAD(Value) OVER(ORDER BY Value) IS NOT NULL THEN ' AND ' ELSE '' END))
,#WhereCondition += CONCAT('[a].', QUOTENAME(Value), ' IS NULL', (CASE WHEN LEAD(Value) OVER(ORDER BY Value) IS NOT NULL THEN ' AND ' ELSE '' END))
FROM STRING_SPLIT(#ColNames,N',')
SELECT #JoinContion, #WhereCondition
String_Split: To split the input string into columns
Lead: to determine if we need the AND keyword when it's not the last row.
Be aware the NOT EXISTS is probably a better solution then LEFT JOIN

Function of ' | ' in sqlplus query

Can somebody tell me what the meaning of the vertical bar ' | ' is in the following sqlplus query?
select distinct z303_id_1 Barcode, ' | ', substr(z303_name,1,35) Name from z36, z303
many thanks
Looks like someone just wanted a column with | characters in it. That query will return three columns:
Barcode containing the value of z303_id_1
An unnamed column with | in it
Name containing the result of substr(z303_name,1,35)

Resources