uuid maybe empty string in postgres - node.js

Here I create an empty table and a function:
CREATE TABLE "ebook_info_t" (
"ebook_id" uuid NOT NULL,
...
PRIMARY KEY ("ebook_id")
);
CREATE OR REPLACE FUNCTION add_ebook_f(
IN author text,
OUT existid uuid, OUT isexist bool)
RETURNS SETOF RECORD AS $$
DECLARE
rc uuid := NULL;
bkname text :=NULL;
BEGIN
SELECT ebook_id,title INTO rc,bkname FROM ebook_info_t WHERE author_name=author;
RAISE EXCEPTION 'bookid=%, title=%',rc,bkname;
END
$$
LANGUAGE plpgsql;
I call this function in nodejs by pg module which version is 6.1.2.
Firstly, table ebook_info_t is empty. I call function add_ebook_f then recieve bookid=3d6171d3-3d45-4869-8e89-b8975a31246b, title=thebookname.
Secondly, I remove WHERE-condition. Then I call it again. I recieve bookid=bac22a64-9cb2-440a-be39-b40d74c2ddfb, title=<NULL>.
Finally, I test this function in pgAdmin4. I shows ERROR: bookid=<NULL>, title=<NULL>.
If the book is not exist, I want to insert it to table. But if I call add_ebook_f in nodejs, I could not judge this book exist or not.
So my question is, how can I insert book info to table if it is not exist? In other words, could I know this book exist?

Related

How to add ticks around a field when using the map function with params for rust?

I need to add ticks around the table name in a MySQL query in Rust but the map function doesn't process what's between the ticks.
What I need is:
conn.exec_batch("INSERT INTO `:table_name` ...",
items.iter().map(|item| params! {
"table_name" => table_name,
However the MySQL error reports that the table name is just a question mark. The function works if I manually insert the table name so I know the rest of the function is working correctly.

How to retrieve result set from postgres stored procedure(or function) using pg

Hi I am working on a web app that uses postgres and some of the sql is in stored procedure/functon. If a function returns a cursor, how can we retrieve and process the resultset in nodejs? I am using pg (node-postgres). Following is the code for the test procedure that I would like to call from nodejs code.
drop table if exists tmp;
create table tmp
(
x integer
);
drop function if exists t1;
create or replace function t1( p_value integer)
returns refcursor
language plpgsql
as $$
declare
ref refcursor;
begin
--insert into tmp(x) values(p_value);
open ref for select x from tmp;
return ref;
end
$$;
This is not how this is done in Postgres. Change it to a set-returning function:
create or replace function t1(p_value integer)
returns table (x integer) --<< adjust here for the real column list
language sql
as $$
insert into tmp(x) values(p_value)
returning x; --<< adjust here for the real column list
$$;
Then use it as part of a SELECT statement:
select *
from t1(42);
Obviously the 42 can be a parameter from your programming language.

Function made of transaction statement on PostgreSQL

I want to authenticate an user by its nickname (networkId) and before-hand hashed password, with an user public table (recoyx.user) and an user private table (recoyx_private.user). The function is based on browsing this PostGraphile tutorial (PostGraphile combines GraphQL and PostgreSQL).
create function recoyx.authenticate(
network_id text,
password_hash text
) returns recoyx.jwt_token
begin;
set local id to (select (numeric_id) from recoyx.user where user.network_id = $1).numeric_id;
select (numeric_id, password_hash)::recoyx.jwt_token
from recoyx_private.user
where user.numeric_id = id and user.password_hash = $2;
end;
The query runner is giving invalid syntax within this function overall, both at the part like select * from recoyx.table where table.field = value, transaction frames and the id binding. I took the query runner from this example which gives a short
facility for initializing, querying and releasing the query runner for the PostgreSQL database (I got here through this postgraphile module API documentation).
When I eliminate this function from my query, it runs fine. As far as I've just seen the dot is valid, and the local assignment too. So is my syntax really wrong?
Update
Now this is my function:
create function recoyx.authenticate(
network_id text,
password_hash text
) returns recoyx.jwt_token
as
$body$
select (numeric_id, password_hash)::recoyx.jwt_token
from recoyx_private.user
where numeric_id = (select numeric_id from recoyx.user where network_id = $1)
and password_hash = $2;
$body$
language sql
stable;
I'm getting undefined relations, but I'm connecting to the default root role that comes within my PostgreSQL installation (postgres role) as I run the create function query
I've put the project on GitHub. I'm running the query through npm run init-database. See environment-example.json (it specifies the conventional "postgres" role).
As documented in the manual the function body is passed as a string in Postgres (and the tutorial you linked to actually included the necessary as $$ ...$$ - you just didn't copy it). You also forgot to specify the function's language.
set local id is neither a valid variable assignment in PL/pgSQL nor in SQL (which doesn't have variables to begin with).
But you don't really need a variable to do what you want, your function can be implemented as a SQL function:
create function recoyx.authenticate(
network_id text,
password_hash text
) returns recoyx.jwt_token
as
$body$
select (numeric_id, password_hash)::recoyx.jwt_token
from recoyx_private.user
where user.numeric_id = (select numeric_id
from recoyx.user
where network_id = $1)
and user.password_hash = $2;
$body$
language sql
stable;

Generate table in hubot brain and insert values

I'm trying to make a table of values inside hubot and he pass it's values to redis-brain.coffee but i just know a way: robot.brain.get("blablabla").
This will get a string from redis-brain and i need some kind of table.
How I'll use it:
At first call of this function, hubot will load the full database to the memory, then, if there's
robot.catchAll (msg) ->
if not quiet
text = msg.message.text
ector.setUser msg.message.user.name
if not loaded_brain
ector_brain = robot.brain.get('ector_brain') #need to be some type of table - In mysql should be like a select
ector.addEntry ector_brain
loaded_brain = true
else
ector.addEntry text
ector_brain = ector_brain+text #this line should insert the value of text inside ector_brain table. -- In mysql shoud be like an insert into
ector.linkNodesToLastSentence previousResponseNodes
response = ector.generateResponse()
previousResponseNodes = response.nodes
msg.reply response.sentence
So, how do I create a table in redis from hubot?
robot.brain.get and robot.brain.set operates with JSON objects, not only strings. Just place an object with your data structure of choice in the brain and get it back when necessary.

How to determine the row id from a column field - SQLite 3, Python

In my SQLite database I have a table called client_dir that is a directory of client contact details. I also have a table called contracts that contains the details of different contracts. I need to be able to create foreign keys that bind a contract entry to a client entry in client_dir.
The thing is , I want to be able to generate the foreign key by just providing the clients name. How do I summon the row id from a field entry?
I think it should look something like this...
def new_contract():
'''creates a new contract entry and links it to a client in the client_dir table'''
client = input("Company name...")
#int(row_id) = client
contract = input("New contract...")
self.cursor.execute("INSERT INTO contracts VALUES (?)",contract,#row_id)
UPDATE
My tables look like this :
self.cursor.execute("""CREATE TABLE client_dir(cli_id INTEGER PRIMARY KEY AUTOINCREMENT, company TEXT, address TEXT, phone INTEGER, email TEXT)""")
self.cursor.execute("""CREATE TABLE contracts(con_id INTEGER PRIMARY KEY AUTOINCREMENT, contract TEXT, client_id INTEGER, FOREIGN KEY(client_id) REFERENCES client_dir(cli_id))""")
and my new _contract method looks like this:
def new_contract(self):
'''creates a new contract entry and links it to a client in the client_dir table'''
client = input("Company name...")
for f_list in self.cursor.execute("SELECT cli_id FROM client_dir WHERE company = (?)",[client]):
f_key = f_list[0]
print(f_key) # For debugging
contract = input("New contract...")
self.cursor.execute("INSERT INTO contracts VALUES (NULL,?,?)",([contract],[f_key]))
print(f_key) is printing a nice tidy 1 on the screen which I am presuming is an int. but I am getting this error:
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
c.new_contract()
File "C:\Python33\smalltime\Client.py", line 63, in new_contract
self.cursor.execute("INSERT INTO contracts VALUES (NULL,?,?)",([contract],[f_key]))
sqlite3.InterfaceError: Error binding parameter 0 - probably unsupported type.
I have fixed this now. The error was due to the fact I was passing in the wrong syntax for the INSERT.
The correct last line of the new_contract method should be:
self.cursor.execute("INSERT INTO contracts VALUES (NULL,?,?)",**([contract,f_key]))**
(previously it had two extra braces : ([contract],[f_key]) and that was throwing it out)
so all that remains to do is remove the print statement and add
self.conn.commit()
to the end.

Resources