creating system table valued function - tsql

Is there a way to create system table valued function that can be run on any DB.
In analogy with SP
use master;
create procedure sp_test
as
begin select 1 end;
exec sys.sp_MS_marksystemobject sp_test
This SP can be executed on any DB within server. I'm looking for same example in TVF.

After going through all forums, there is no way to make system functions. Only stored procedures and tables can be done system.

Is using the database name when referencing the function an option? If so you could just create your function...
USE Master
GO
CREATE FUNCTION dbo.yourITVF()
RETURNS TABLE AS RETURN
SELECT * FROM <some table>;
GO
Then run it like this from any DB on the instance:
SELECT * FROM master.dbo.yourITVF();

Related

DB2oC (DB2 on Cloud) : Facing "attempted to modify data but was not defined as MODIFIES SQL DATA" error

I have created very simple function in DB2oC as below, which has one UPDATE sql statement and one SELECT sql statement along with MODIFIES SQL DATA. But still I get the below error, though I have specified MODIFIES SQL DATA. I did GRANT ALL on that TEST table to my user id and also did GRANT EXECUTE ON FUNCTION to my user id on safe side. Can you please help to explain on what could be the issue?
I have simply invoked the function using SELECT statement like below:
SELECT TESTSCHEMA.MAIN_FUNCTION() FROM TABLE(VALUES(1));
SQL Error [38002]: User defined routine "TESTSCHEMA.MAIN_FUNCTION"
(specific name "SQL201211013006981") attempted to modify data but was
not defined as MODIFIES SQL DATA.. SQLCODE=-577, SQLSTATE=38002,
DRIVER=4.27.25
CREATE OR REPLACE FUNCTION MAIN_FUNCTION()
RETURNS VARCHAR(20)
LANGUAGE SQL
MODIFIES SQL DATA
BEGIN
DECLARE val VARCHAR(20);
UPDATE TEST t SET t.CONTENT_TEXT = 'test value' WHERE t.ID = 1;
select CONTENT_TEXT into val from TEST where ID = 1;
return val;
end;
Appreciate your help.
For the modifies SQL data clause , the usage of the function is restricted on Db2-LUW.
These restrictions do not apply for user defined functions that do not modify data.
For your specific example, that UDF will operate when used as the sole expression on the right hand side of an assignment statement in a compound-SQL compiled statemnent.
For example:
create or replace variable my_result varchar(20) default null;
begin
set my_result = main_function();
end#
Consider using stored procedures to modify table contents, instead of user defined functions.
You could avoid using a function, and just use a single "change data statement"
SELECT CONTENT_TEXT
FROM NEW TABLE(
UPDATE TEST t
SET t.CONTENT_TEXT = 'test value'
WHERE t.ID = 1
)

PostgreSQL select INTO function

I am writing a function which will select and SUM the resulting output into a new table-therefore I attempted to use the INTO function. However, my standalone code works, yet once a place into a function I get an error stating that the new SELECT INTO table is not a defined variable (perhaps I am missing something). Please see code below:
CREATE OR REPLACE FUNCTION rev_1.calculate_costing_layer()
RETURNS trigger AS
$BODY$
BEGIN
-- This will create an intersection between pipelines and sum the cost to a new table for output
-- May need to create individual cost columns- Will also keep infrastructure costing seperated
--DROP table rev_1.costing_layer;
SELECT inyaninga_phases.geom, catchment_e_gravity_lines.name, SUM(catchment_e_gravity_lines.cost) AS gravity_sum
INTO rev_1.costing_layer
FROM rev_1.inyaninga_phases
ON ST_Intersects(catchment_e_gravity_lines.geom,inyaninga_phases.geom)
GROUP BY catchment_e_gravity_lines.name, inyaninga_phases.geom;
RETURN NEW;
END;
$BODY$
language plpgsql
Per the documentation:
CREATE TABLE AS is functionally similar to SELECT INTO. CREATE TABLE AS is the recommended syntax, since this form of SELECT INTO is not available in ECPG or PL/pgSQL, because they interpret the INTO clause differently. Furthermore, CREATE TABLE AS offers a superset of the functionality provided by SELECT INTO.
Use CREATE TABLE AS.
Although SELECT ... INTO new_table is valid PostgreSQL, its use has been deprecated (or, at least, "unrecommended"). It doesn't work at all in PL/PGSQL, because INSERT INTO is used to get results into variables.
If you want to create a new table, you should use instead:
CREATE TABLE rev_1.costing_layer AS
SELECT
inyaninga_phases.geom, catchment_e_gravity_lines.name, SUM(catchment_e_gravity_lines.cost) AS gravity_sum
FROM
rev_1.inyaninga_phases
ON ST_Intersects(catchment_e_gravity_lines.geom,inyaninga_phases.geom)
GROUP BY
catchment_e_gravity_lines.name, inyaninga_phases.geom;
If the table has already been created an you just want to insert a new row in it, you should use:
INSERT INTO
rev_1.costing_layer
(geom, name, gravity_sum)
-- Same select than before
SELECT
inyaninga_phases.geom, catchment_e_gravity_lines.name, SUM(catchment_e_gravity_lines.cost) AS gravity_sum
FROM
rev_1.inyaninga_phases
ON ST_Intersects(catchment_e_gravity_lines.geom,inyaninga_phases.geom)
GROUP BY
catchment_e_gravity_lines.name, inyaninga_phases.geom;
In a trigger function, you're not very likely to create a new table every time, so, my guess is that you want to do the INSERT and not the CREATE TABLE ... AS.

PostgreSQL isset function

Is there any way, how to check, whether a variable has already been set in my environment?
Example:
\set table_name countries
\i queries.sql
queries.sql:
SELECT * FROM :table_name;
I want to make queries.sql to be called independently and use some default table name I would specify.
Is this possible or do I really need to create another SQL file through which I will call the queries (\i)?
My use case is usage of my SQL queries both in pgTAP unit tests (with some sample table names) and independently.
You could check the current value with:
SELECT :'table_name';
You can set it on the call to psql with something like --set='table_name' on the psql command line.

Execute triggers function of another schema on the actual chema

my problem is easy to explain with an example: I have a 'common' schema (the public one?) where I store common data between a clustered application.
For every instance of my application, I have a role (used as the application user).
And i have a common role, app_users, with read-only privileges on the common schema, and every application role is a member of app_users.
Now my problem is: how can i set a trigger on the app_a scheme that execute a function (procedure) in the common scheme, but affect the (and only the) app_a tables?
I mean:
// common_scheme, dummy function to emulate the mysql on update = now()
CREATE OR REPLACEFUNCTION update_etime() RETURNS TRIGGER AS $$
BEGIN
NEW.etime = date_part('epoch'::text, now())::int;
RETURN NEW;
END;
$$ language plpgsql;
// now, in the app_foo scheme, i have the table:
CREATE TABLE foo_table (fid serial not null primary key unique, label char(25));
// and the trigger:
CREATE TRIGGER foo_table_update_etime BEFORE UPDATE ON foo_talbe FOR EACH ROW EXECUTE PROCEDURE update_etime();
// ERROR: function update_etime() does not exist
CREATE TRIGGER foo_table_update_etime BEFORE UPDATE ON foo_talbe FOR EACH ROW EXECUTE PROCEDURE common_scheme.update_etime();
// ERROR: function common_scheme.update_etime() does not exist
The user that will access app_foo has the execute privilege on update_etime() function in common_schema.
Any idea?
I've googled around but the only solution I fount to call functions from other schemas is something like execute 'select * from ' || schema_name || '.table_name'; but i dont think this will do the trick in my case, becose the function must work with the 'local' scheme.
Your second set of syntax should work... the one with "EXECUTE PROCEDURE common_scheme.update_etime();"
If it isn't finding the function, I'd guess that you either have created it in a different schema than you think it is in, or you haven't created it at all (and note, your example create syntax has a bug, no space between "replace" and "function", which would cause an error when trying to create the function. Try doing a:
\df *.update_etime
As superuser to verify the function exists and is in the location you think it is in. HTH.

Execute Stored Process with pass in SQL query from another table?

Currently my development environment is using SQL server express 2008 r2 and VS2010 for my project development.
My question is like this by providing a scenario:
Development goal:
I develop window services something like data mining or data warehousing using .net C#.
That meant I have a two or more database involved.
my senario is like this:
I have a database with a table call SQL_Stored inside provided with a coloum name QueryToExec.
I first idea that get on my mind is written a stored procedure and i tried to came out a stored procedure name Extract_Sources with two parameter passed in thats ID and TableName.
My first step is to select out the sql need to be execute from table SQL_Stored. I tried to get the SQL by using a simple select statement such as:
Select Download_Sql As Query From SQL_Stored
Where ID=#ID AND TableName=#TableName
Is that possible to get the result or is there another way to do so?
My Second step is to excecute the Sql that i get from SQL_Stored Table.Is possible to
to execute the query that select on the following process of this particular stored proc?
Need to create a variable to store the sql ?
Thank you,Appreciate for you all help.Please don't hesitate to voice out my error or mistake because I can learn from it. Thank you.
PS_1:I am sorry for my poor English.
PS_2:I am new to stored procedure.
LiangCk
Try this:
DECLARE #download_sql VARCHAR(MAX)
Select
#download_sql = Download_Sql
From
SQL_Stored
Where
AreaID = #AreaID
AND TableName = #TableName
EXEC (#download_sql)