When creating a function, Oracle allows the following syntax:
CREATE OR REPLACE FUNCTION
Is something similar also possible in HSQL? I.e. creating a function, avoiding an error if it already exists and replacing it instead?
CREATE OR REPLACE is supported in ORA compatibility mode but it works only when the function does not exist.
The ALTER SPECIFIC ROUTINE syntax is supported when the function does exist and allows you to change the body of the function without changing its parameter.
You can use SELECT * FROM INFORMATION_SCHEMA.ROUTINES to check if a function exists.
Related
This is a crazy one, seems like a bug to me. I changed the signature of a scalar user function to include an additional parameter, and I was trying to refactor my sprocs which call it, and I noticed an issue which I was able to recreate with two test functions.
First, I created a scalar user function called "test_function" which take a single integer parameter. It doesn't matter what the function does for this test.
Then I created a sproc, which has a simple temp table of 1 column value "thevalue"
Then I execute the alter or create update, but without the parameter:
Intellisense correctly indicates that there's a parameter missing in test_function. But here's where the problem occurs, I can still create or alter this sproc without any errors!
However, if I remove the temp table from the equation, and update a variable, I get the expect error when trying to create or alter the sproc:
Is there a possible setting or a way to flag this specific sproc so that the error would occur and the sproc not be altered?
I have this function
how i use it without a trigger ?
There are a few possible alternatives doing so without a trigger, it depends on when you want to call this function.
using cron:
*/15 * * * * psql -d mydatabase -c "interv()"
using LISTEN: https://www.postgresql.org/docs/current/sql-listen.html
Functions are used throughout your database, they can be called from within stored procedures as well. Functions should return something. So if you have a date in one format and want to convert it into a different format, you can create a function that does just that, and 'call' that function within a stored procedure, for example.
What is the correct syntax to create an inline scalar function in SQL Server?
Books Online, in the Types of Functions chapter (2005 and up), talks about Inline Scalar Functions as if they exist and as if no BEGIN...END block is required (in contrast with multiline functions):
For an inline scalar function, there is no function body; the scalar
value is the result of a single statement. For a multistatement scalar function, the function body, defined in a BEGIN...END block, contains a series of Transact-SQL statements that return the single value.
I also noticed a row for "IS: inline scalar function" in the list of object types in the spt_values table:
SELECT name
FROM master..spt_values
WHERE type = 'O9T'
AND name LIKE '%function%'
I have tried to create such a function with no success:
CREATE FUNCTION AddOne(#n int) RETURNS int
AS
RETURN #n + 1
The error message is
Msg 102, Level 15, State 31, Procedure AddOne, Line 3 Incorrect syntax
near 'RETURN'.
Am I missing something or is there an error in Books Online?
Well, AFAIK, none exist (not even in the hidden [mssqlsystemresource] database) and there's no syntax to create one. So it appears that this is something that Microsoft must have anticipated in the run-up to SQL Server 2005 by adding a type for it (and doc!), but never actually implemented for some reason.
Though it is one of the single most requested features for all of Ms Sql Server. Primarily because the default UDF's are so slow and we end up having to back-end ITVF's to get the same effect. (difficult and clumsy, but it works).
Correct, there is no such thing as a inline scalar function. One can be "simulated" by using an inline-TVF, however, the syntax of any "clients" will need to change.
1) create he function:
create function dbo.AddOne(#input int) returns table as return (select #input + 1 as value);
2) in the "client" code, do this...
(select value from dbo.AddOne(Column)) as ColumnPlusOne
An now you have a functioning inline scalar function.
I've had to do this to replace a lot of scalar UDFs in my client code that looked like this...
create function dbo.GetLookupID(#code varchar(50)) returns int
as
begin
declare #return int;
select #return = LookupID from dbo.Lookups where Code = #code;
return #return;
end;
I tried fixing it by removing the variable...
create function dbo.GetLookupID(#code varchar(50)) returns int
as
begin
return (select LookupID from dbo.Lookups where Code = #code);
end;
That was an improvement, however, there was still an unpleasant performance hit. When I changed to the iTVF and changed the calling convention.... it got much better.
Starting with SQL Server 2019 CTP2.1, there is a new feature called "Scalar UDF inlining" which can automatically inline scalar UDFs when certain preconditions are satisfied.
The official blog post introducing the feature is here: https://blogs.msdn.microsoft.com/sqlserverstorageengine/2018/11/07/introducing-scalar-udf-inlining/
Detailed documentation that describes the feature is here:
https://learn.microsoft.com/en-us/sql/relational-databases/user-defined-functions/scalar-udf-inlining?view=azuresqldb-current
I'm seeing the same thing. That sentence seems to be the only reference to "inline scalar functions". This article claims that inline table-valued functions can be fast enough to do the job.
here is parts of my stored procedure that can not find the function:
(dbo.fn_Get_Order_Contacts_Info_Full_Name(#order_detail_ID, 'Borrower')) As 'Borrower_Contact_Info_Full',
replace(dbo.fn_get_business_product_element_requirements(t_order_detail.order_detail_id,288)
the functions exist in a scalar function as following:
ALTER FUNCTION [dbo].[fn_Get_Order_Contacts_Info_Full_Name]
(
ALTER FUNCTION [dbo].[fn_get_business_product_element_requirements]
(
is there a reason why the proceedure can not find the scalar functions.
my error:
can not find column "dbo" or the user defined function or aggregate " the 2 functions above", or the name is ambiguous.
It's a bit harder to tell without seeing the whole query but here are things to look at:
Are the functions in the database(s) you are refering to in the query?
Did you accidentally create them in two databases, both of which are
referenced in the query?
Are you positive you have typed the names correctly and that they are
in dbo?
Are you sure those are scalar functions?
Have you refreshed the database?
So the way I fixed this issue was with a closure of SQL and restart of the server and it worked. Seems to be a bug in sql server.
I have to execute a loop in database. This is only a one time requirement.
After executing the function, I am dropping the function now.
Is there any good approach for creating temporary / disposable functions?
I needed to know how to do a many time use in a script I was writing. Turns out you can create a temporary function using the pg_temp schema. This is a schema that is created on demand for your connection and is where temporary tables are stored. When your connection is closed or expires this schema is dropped. Turns out if you create a function on this schema, the schema will be created automatically. Therefore,
create function pg_temp.testfunc() returns text as
$$ select 'hello'::text $$ language sql;
will be a function that will stick around as long as your connection sticks around. No need to call a drop command.
A couple of additional notes to the smart trick in #crowmagnumb's answer:
The function must be schema-qualified at all times, even if pg_temp is in the search_path (like it is by default), according to Tom Lane to prevent Trojan horses:
CREATE FUNCTION pg_temp.f_inc(int)
RETURNS int AS 'SELECT $1 + 1' LANGUAGE sql IMMUTABLE;
SELECT pg_temp.f_inc(42);
f_inc
-----
43
A function created in the temporary schema is only visible inside the same session (just like temp tables). It's invisible to all other sessions (even for the same role). You could access the function as a different role in the same session after SET ROLE.
You could even create a functional index based on this "temp" function:
CREATE INDEX foo_idx ON tbl (pg_temp.f_inc(id));
Thereby creating a plain index using a temporary function on a non-temp table. Such an index would be visible to all sessions but still only valid for the creating session. The query planner will not use a functional index, where the expression is not repeated in the query. Still a bit of a dirty trick. It will be dropped automatically when the session is closed - as a depending object. Feels like this should not be allowed at all ...
If you just need to execute a function repeatedly and all you need is SQL, consider a prepared statement instead. It acts much like a temporary SQL function that dies at the end of the session. Not the same thing, though, and can only be used by itself with EXECUTE, not nested inside another query. Example:
PREPARE upd_tbl AS
UPDATE tbl t SET set_name = $2 WHERE tbl_id = $1;
Call:
EXECUTE upd_tbl(123, 'foo_name');
Details:
Split given string and prepare case statement
If you are using version 9.0, you can do this with the new DO statement:
http://www.postgresql.org/docs/current/static/sql-do.html
With previous versions, you'll need to create the function, call it, and drop it again.
For ad hock procedures, cursors aren't too bad. They are too inefficient for productino use however.
They will let you easily loop on sql results in the db.