I've done a lot of searching, but been unable to find the answer to the problem I have below. Which I'm sure has a very simple answer.
I'm trying to create a static timestamp, which I'll be able to use through out my stored procedure.
So in the instance below, I'm trying to write the CURRENT_TIMESTAMP() to a variable, then calling it in an update statement.
The output I get in the table is "[object Object]", this is currently a varchar column. Ideally want it to input into a timestamp column, but was getting an error.
CREATE OR REPLACE PROCEDURE SP_TEST_RUN()
RETURNS VARCHAR
LANGUAGE JAVASCRIPT
AS
$$
var STORE_DATE1= snowflake.execute({sqlText: "select CURRENT_TIMESTAMP()"});
snowflake.execute({sqlText: "UPDATE MY_TABLE SET TOKEN_1 = '" + STORE_DATE1 +"';" });
$$;
Many thanks in advance!
The execute command returns a resultset from which you need to select the value you want. There are lots of examples of this in the documentation - look for the getColumnValue method
With NickW help, managed to figure it out!
As NickW rightly points out, need to use getColumnValue, this will then loop though the results, as there is only 1 entry. Only needs to occur once.
One thing to note, I had to add "toISOString()" to the variable, which converts the JAVA variable to a TIMESTAMP SQL can understand, otherwise JAVA will automatically convert the Timestamp to a string.
CREATE OR REPLACE PROCEDURE SP_TEST_RUN()
RETURNS VARCHAR
LANGUAGE JAVASCRIPT
AS
$$
var STORE_DATE1= snowflake.execute({sqlText: "select CURRENT_TIMESTAMP()"});
while (STORE_DATE1.next())
{
var STORE_DATE2 = STORE_DATE1.getColumnValue(1);
}
snowflake.execute({sqlText: "UPDATE MY_TABLE SET INSERT_DATE_TIME = '" + STORE_DATE2.toISOString() +"';" });
$$;
Related
For some reason, every time I run exec
communications_getCode #telCode='MX'
I get empty results. I know I am missing something because if I run
Select * from tbl_telCode where code = 'MX'
I get results (1 to be precise). But if I try it with the procedure, I get blank results
CREATE PROCEDURE dbo.communications_getCode
#telcode varchar
AS
SELECT
id, code, detail
FROM
tbl_telCode
WHERE
[code] = #telcode;
I do not know what am I missing.
The varchar in the declaration defaults to varchar(1). When you pass a longer string, it gets truncated to one character.
In SQL Server, always user a length with string definitions:
CREATE PROCEDURE dbo.communications_getCode (
#telcode varchar(255)
) AS
BEGIN
SELECT id, code, detail
FROM tbl_telCode
WHERE [code] = #telcode;
END;
Note that the body of the stored procedure is wrapped in a BEGIN/END. I find this to be a useful practice.
Also, there is no reason to define a stored procedure for this. In my opinion, this would be better defined as a function.
I'm update the money for one person only in a database. The money is saved as a currency and the email as a string. My SQL is throwing a syntax error
ADOQuery.sql.text:= ' UPDATE TblPlayerdetails SET Money = "' + Inttostr(NewAmount) + '" WHERE Email = "' + Playersemail + '"';
Newamount is an integer and email is a string.
I was hoping you would manage to work out what to do from the documentation I linked in comments, but on reflection I thought I had better provide a correct answer.
Set up the following code
procedure TForm1.Button1Click(Sender: TObject);
begin
AdoQuery2.SQL.Text := 'update moneytable set money = :money where id = :id';
AdoQuery2.Parameters.ParamByName('ID').Value := 1;
AdoQuery2.Parameters.ParamByName('Money').Value := 99;
AdoQuery2.ExecSQL;
end;
The line
AdoQuery2.SQL.Text := 'update moneytable set money = :money where id = :id';
sets up a parameterised UPDATE statement. The :id and :money are placeholders for parameter values which will be provided separately. The parameter names are ID and Money, though they could be given other names. Note that you could set up AdoQuery2's SQL.Text in the IDE at design time if you wanted to.
The next two lines
AdoQuery2.Parameters.ParamByName('ID').Value := 1;
AdoQuery2.Parameters.ParamByName('Money').Value := 99;
specify the values which the parameters are to be set to for when the UPDATE is actually executed. The ID value is the Row iD (aka primary key) of the row in the table which is to be updated. Before the UPDATE staement is actually executed, the AdoQuery parses the SQL and creates the parameters if they don't alteady exist (you can create them at design time in the IDE by editing the Parameters property of the AdoQuery.
Finally
AdoQuery2.ExecSQL;
is what actually executes the UPDATE statement. Note that you can repeat the steps of setting the parameter values and calling ExecSQL as many times as you want.
The main thing which was wrong with your UPDATE statement was that you were using double-quote (") marks, whereas when a SQL statement needs quote marks (and values of numeric columns do NOT) they should be single quotes('). A complication when constructing a SQL statement in Delphi code is that its syntax requires single quotes which are to be embedded in the SQL to be doubled up.
Note also that you should always used parameterised SQL for your SELECT, UPDATE, INSERT and DELETE statements as this helps protect your app against Sql injection. Making, say, an unparameterised statement accessible to the user can allow a malicious user to attempt to execute any SQL they wish.
In your question, you did not indicate what type of column is 'Money'. If it's varchar, char, then I understand why you might convert NewAmount to a string.
However, if the database expects numeric value (because the field is of type int, double, dec, or float), the syntax would be SET Money= '+ NewAmount +'.
I need to get a userstamp into a table and have not managed to figure out how the GENERATED FOR EACH ROW ON UPDATE AS statement works with the SESSION_USER variable in DB2 10.5 (LUW).
Managed to get an implementation working using a function which has a fake variable for forcing the evaluation in update statements:
CREATE OR REPLACE FUNCTION XXX.CURRENT_USER( tmp varchar(128))
SPECIFIC xxx.XXX_CURRENT_USER
RETURNS VARCHAR(128)
CONTAINS SQL DETERMINISTIC NO EXTERNAL ACTION
BEGIN
RETURN session_user ;
END
GO
CREATE TABLE xxx (
i INTEGER,
t VARCHAR(128) GENERATED ALWAYS AS (XXX.CURRENT_USER(i))
)
However, would be nice have less "hacky" implementation for a basic thing like this.
For the time stamps there is that "FOR EACH ROW ON UPDATE AS ROW CHANGE TIMESTAMP" statement but no equivalent for other register variables it seems.
Help is very much appreciated
Does this work?
CREATE TABLE xxx (
i INTEGER,
t VARCHAR(128) WITH DEFAULT session_user
);
I don't have DB2 on hand to check, but this is very similar to the syntax used in other databases (although the more typical syntax does not use WITH).
Hi I am trying to learn how to use Full text search in postgres using version 9.2.2.
Here is my database:
title : character varying(1024)
body : text
body_title_tsv | tsvector
I then defined the body_title_tsv to be a ts_vector made up from body and title fields, with coalesce to handle nulls.
UPDATE pg_rocks_post SET body_title_tsv = to_tsvector( coalesce(body,'') || coalesce (title,''));
I want to know how to write a TRIGGER that handles updates on "title" and/or "body".
I know I can create a Trigger using syntax like this and the tsearch2 function.
CREATE TRIGGER body_title_tsv_trig BEFORE UPDATE OR INSERT on pg_rocks_post
FOR EACH ROW EXECUTE PROCEDURE tsearch2(body_title_tsv , title);
I can do the same with body instead of title.
My Question is how do I combine the two to update the body_title_tsv
Or do I have to learn how to write my own function that essentially runs the
SQL for body_title_tsv when UPDATE occurs? .
I know the other way to address this issue is to create an INDEX. But I am trying to understand how to write a trigger and read examples that use tsearch2 in the PostgreSQL book by Kory and Susan Douglas.
Edit: I came across this function that does this . Its the "tsvector_update_trigger" function. I am still interested in knowing if there is a way to do this using tsearch2.
create trigger body_title_tsv_trig BEFORE UPDATE OR INSERT on pg_rocks_post FOR EACH ROW EXECUTE PROCEDURE tsvector_update_trigger(body_title_tsv,'pg_catalog.english',title,body);
I would go about this somewhat differently. It seems like you want a consistent search interface for your table, and the best way to do this is to design it in a function. You can then index the output of the function. Note the function does not hit the table, and only operates on tuple data, and this is why we can index its output safely.
CREATE OR REPLACE FUNCTION tsv(pg_rocks_post) RETURNS tsvector LANGUAGE SQL AS
$$
SELECT tsvector(coalesce($1.title, '') || ' ' || coalesce($1.body, ''));
$$;
Now I can:
SELECT tsv(p) FROM pg_rocks_post p;
and it will just work. I can also use the following form which would be more useful in some cases:
SELECT p.tsv FROM pg_rocks_post.p;
or
SELECT * from pg_rocks_post p WHERE plainto_tsquery('fat cat') ## p.tsv;
Note you cannot omit the table alias since p.tsv is converted to tsv(p) as a function call. This is nice object-like syntactic sugar that can make your life easier with PostgreSQL.
The next step is in indexing the output of the function:
CREATE INDEX pg_rocks_post_tsv_idx ON pg_rocks_post(tsv(pg_rocks_post));
There we go. no trigger needed and you get the index on the derived data.
In SQL Server I could copy sql code out of an application and paste it into SSMS, declare & assign vars that exist in the sql and run. yay great debugging scenario.
E.g. (please note I am rusty and syntax may be incorrect):
declare #x as varchar(10)
set #x = 'abc'
select * from sometable where somefield = #x
I want to do something similar with Postgres in pgAdmin (or another postgres tool, any recommendations?) where I can just drop my SQL (params & all) into something that will run against Postgres DB.
I realise you can create pgscript, but it doesn't appear to be very good, for example, if I do the equivalent of above, it doesn't put the single quotes around the value in #x, nor does it let me by doubling them up and you don't get a table out after - only text...
Currently I have a piece of SQL someone has written that has 3 unique variables in it which are used around 6 times each...
So the question is how do other people debug SQL efficiently, preferably in a similar fashion to my SQL Server days.
You can achieve this using the PREPARE, EXECUTE, DEALLOCATE commands for handling statements, which is really what we are talking about here.
For example:
PREPARE test AS SELECT * FROM users WHERE first_name = $1;
EXECUTE test ('paul');
DEALLOCATE test;
Perhaps not as graphical as some may like, but certainly workable.
I would give a shot at writing a SQL function that wraps your query. It can be something as simple as
CREATE OR REPLACE FUNCTION my_function(integer, integer)
RETURNS integer
AS
$$
SELECT $1 + $2;
$$
LANGUAGE SQL;
SELECT my_function(1, 2);
I would do this instead of a PREPARE since it will be simpler to update it. Depending on how complex the function is, you might want to also look at some of the other PL's in Postgres.
SQL procs are notoriously hard to debug. My lame but practical solution has been to write log messages to a log table, like this (please excuse syntax issues):
create table log_message (
log_timestamp timestamp not null default current_timestamp,
message varchar(1000)
);
then add lines to your stored proc like:
insert into log_message (message) values ("The value of x is " || #x);
Then after a run:
select * from log_message order by 1;
It's not pretty, but works in every DB.