It turns out that a function is just a procedure that returns something. If you look in the sysprocedure table the is-a-function flag is set for that routine even though it was created as a procedure. In some situations it matters how you call it, apparently not from inside c a trigger action.
Art S. Kagel, President and Principal Consultant
ASK Database Management Corp.
Original Message:
Sent: Thu June 05, 2025 06:26 PM
From: Jacob Salomon
Subject: Cast a datetime to character in default clause
Thanks much, Art.
I did make a couple of changes from your prescription: (If I hadn't, you would wonder if it was really me. :-)
WHEN ((neu.two IS NULL ) )
Why the double parentheses? I took off one pair and it still created the trigger just fine. Haven't had the chance to test it out yet, however.- You created the procedure but executed function. While experiencing some errors trying to emulate your code I changed to to
execute procedure
. Since it compiled fine I'll leave it as is. I do note that in your demo code it worked as you coded it.
Question: Had you created it as a function, would I have been able to say let neu.creat_time = get_time_str()
?
I must also credit Paul Watson for his article on certain errors that my imperfect emulation was generating. He pointed out exactly how I was deviating to cause error:
732: Incorrect use of old or new values correlation name inside trigger.
When I get up to the update trigger I'll likely have more to ask. But I'll jump off that bridge when I come to it. (Overconfident fellow, ain't he? ;-)
------------------------------
Jacob Salomon
Original Message:
Sent: Thu June 05, 2025 02:10 PM
From: Art Kagel
Subject: Cast a datetime to character in default clause
Jacob:
I would just bite the bullet and go with an INSERT TRIGGER on that column:
CREATE PROCEDURE "art".get_time_str () returning char(8);
return (current hour to second)::char(8);
end procedure;
CREATE TABLE "art".for_jake (
one SERIAL(3) NOT NULL,
two CHAR(8)
);
CREATE TRIGGER "art".time_for_jake
INSERT ON "art".for_jake
REFERENCING NEW AS neu
FOR EACH ROW
WHEN ((neu.two IS NULL ) )
(
EXECUTE function "art".get_time_str() INTO "art".for_jake.two);
$ dbaccess testdb -
Database selected.
> insert into for_jake( one ) values ( 0 );
1 row(s) inserted.
> insert into for_jake( one ) values ( 0 );
1 row(s) inserted.
> select * from for_jake;
one two
1 14:06:16
2 14:06:21
2 row(s) retrieved.
>
Database closed.
------------------------------
Art S. Kagel, President and Principal Consultant
ASK Database Management Corp.
www.askdbmgt.com
Original Message:
Sent: Thu June 05, 2025 01:31 PM
From: Jacob Salomon
Subject: Cast a datetime to character in default clause
Hi Y'all. (English REALLY needs a plural "you"!)
I have a situation where a commercial software package goes bananas with datetime data types. But it is happy to work with a time stamp if it is character data type.
I have been tasked with adding a few columns to a table. I am trying to set some defaults on the columns. It uses separate date and time columns so the date partis easy: creation_time date default today,
Now the time stamp part, most easily expressed as datetime hour to second, is the problem: I need it inserted as a character string. Of course the following will not work but it is effectively what I'm trying to do:
create_time char(8) default current hour to second,
The default value is not compatible with the data type. So I tried to cast it to character:
create_time char(8) default (current hour to second)::char(8),
# ^
# 201: A syntax error has occurred.
A not-unreasonable complaint. BTW, if I take off the parentheses the syntax error moved to the :: of the cast operator.
I may also need to do something similar in a trigger, inserting a datetime hour to second
value as a char(8)
in another column. The documentation on casting does not seem to cover this type of conversion.
I would LOVE some ideas here!
Thanks much!
------------------------------
Jacob Salomon (Needing a new snarky signature.)
------------------------------