I have the following tasks in SSIS:
In Check Stock task, I execute a stored procedure which returns 0 or 1:
CREATE PROCEDURE [dbo].[SP_CheckStockAvailability]
AS
BEGIN
DECLARE #ItemGID nvarchar(250)=(SELECT TOP (1) ItemGID FROM XMLOrderlines WHERE Comparison='0')
SELECT CASE
WHEN #ItemGID IS NOT NULL
THEN CAST (0 AS bit)
ELSE CAST (1 AS bit)
END AS Comparison
FROM XMLOrderlines
END
GO
I would like to execute Reject Order (on the right) task if the result is 1 and, if not, to execute the one from the left. I set to export the result of the procedure in a variable, Boolean data type with a default value of "False".
If I edit the precedence constraint and I set Expression as evaluation operation and then choose the variable from the previous task, either way it does not go to the next task that is supposed to. What am I missing? I tried what I found on the web but nothing helped me. Thanks!
Solution
You have to set the following values:
Reject Order
Evaluation operation: Expression and Constraint
Value: Success
Expression: #[User::Result] = 1
OR
#[User::Result]
Accept Order
Evaluation operation: Expression and Constraint
Value: Success
Expression: #[User::Result] = 0
OR
!#[User::Result]
Screenshot
Suggestions
I think it is better to add a TRY...CATCH block to your procedure, so if it encounters an error the result will be 1 and the Order is rejected:
CREATE PROCEDURE [dbo].[SP_CheckStockAvailability]
AS
BEGIN
BEGIN TRY
DECLARE #ItemGID nvarchar(250)=(SELECT TOP (1) ItemGID FROM XMLOrderlines WHERE Comparison='0')
SELECT CASE
WHEN #ItemGID IS NOT NULL
THEN CAST (0 AS bit)
ELSE CAST (1 AS bit)
END AS Comparison
FROM XMLOrderlines
END TRY
BEGIN CATCH
SELECT 1 AS Comparison
END CATCH
END
GO
Try choosing Evaluation Operation to Expression and Constraint and the expression has to be smth like #[User::Result] = 1. The expression has to return True or False.
For more informations, follow this link:
Working with Precedence Constraints in SQL Server Integration Services
The expression for 1/True should be #[User::Result], as you have, and the expression for 0/False should be !#[User::Result] (notice the exclamation mark).
You may also want to look into using "Expression and Constraint" as an "Evaluation operation", as without that, the flow will continue regardless of whether "Check stock" succeeds or fails (unless that is the desired behaviour). The "Constraint" part of this is what the "Value" field represents - in your image it is set to Failure, but greyed out (due to having only "Expression" selected) and therefore inactive.
We have a function that needs to select items from a linked server, like
Alter function dbo.ttest1()
returns int
as
begin
SELECT * FROM LINKED_SERVER.Database.Schema.Table
WHERE .....
RETURN 0
end
In case of the remote server is not available, the function will throw out the error saying connection failed, but I want to cover it and let it return a default value.
Since this is compile-level error, BEGIN TRY --- END TRY is not able to cover it, what's worse, since we are in function, EXEC(#string),sp_executesql, SELECT * FROM OPENQUERY('...'), sp_testlinkedserver none of them works. the worst, I cannot afford to take risk of changing it into an SP (the grammar SELECT dbo.ttest1() is penetrated everywhere in the project).
Are there any good solutions?
I am writing a postgresql function but I cannot seem to find where the error is. Postgresql is at version 9.4.
The following is the function:
CREATE FUNCTION custom_function1()
RETURNS trigger
LANGUAGE plpgsql
AS
$$
DECLARE base_val integer;
BEGIN
base_val := (EXTRACT(YEAR FROM now())::integer * 10000000000);
IF (currval('custom_sequence') < base_val) THEN
setval('custom_sequence', base_val);
END IF;
NEW.id := custom_function2();
RETURN NEW;
END;
$$;
My custom_sequence is in the format YYYY0000000000 (ex. 20150000000000).
So what this basically does (should do) is it checks if the base_val (minimum value for current year) is greater then the currval (current custom_sequence value) and updates the custom_sequence value. Then it returns a new value for that sequence generated with the function custom_function2 (which formats it slighly).
When I try to execute this it gives me:
syntax error at or near "setval"
I am pretty new to both postgresql and writing functions so I am probably not seeying an obvious error. If someone could help me it would be highly appreciated, thank you.
The error is related to what's explained in the doc here:
40.5.2 Executing a Command With No Result
[...]
Sometimes it is useful to evaluate an expression or SELECT query but
discard the result, for example when calling a function that has
side-effects but no useful result value. To do this in PL/pgSQL, use
the PERFORM statement:
PERFORM query;
You should write:
PERFORM setval('custom_sequence', base_val);
There's a situation like: If the Salary column in updated with a value lesser than it's original value, print an error message and let the update NOT happen. This is what I've written so far:
CREATE OR REPLACE TRIGGER TRIG1
BEFORE UPDATE OF SAL ON EMP
for each row
USER_XCEP EXCEPTION
WHEN (NEW.SAL<OLD.SAL)
BEGIN
RAISE USER_XCEP
EXCEPTION
WHEN USER_XCEP THEN
DBMS_OUTPUT.PUT_LINE('UPDATION NOT ALLOWED - ILLEGAL VALUES');
END;
And I get the error - Incorrect Trigger Specification
Is there any other way to achieve this?
You're almost there; you need a DECLARE block in a trigger if you want to declare anything; this means that your WHEN clause is in the wrong place.
create or replace trigger trig1
before update
of sal
on emp
for each row
when (new.sal < old.sal)
declare
user_xcep EXCEPTION;
PRAGMA EXCEPTION_INIT( user_xcep, -20001 );
begin
raise user_xcep;
end;
SQL Fiddle
A few points:
Never catch an exception and then call DBMS_OUTPUT.PUT_LINE; it's pointless. Someone has to be there to view the result for each and every record. If you don't want something to happen raise the exception and then catch it. I've added an error code to your exception so that you can catch this outside the trigger and handle it how you wish (don't print anything to stdout).
It's a minor point but I've added a little whitespace; not much. I couldn't initially see where the problem was with your code because you didn't have any.
You were missing semi-colons after the exception declaration and RAISE.
Read more about internally defined exceptions in the documentation
Hi I am using postgresql 8.1.22, I am trying to setup postgresql auditing using the following function.
CREATE OR REPLACE FUNCTION audit.if_modified_func() RETURNS TRIGGER AS $body$
DECLARE
v_old_data TEXT;
v_new_data TEXT;
BEGIN
/* If this actually for real auditing (where you need to log EVERY action),
then you would need to use something like dblink or plperl that could log outside the transaction,
regardless of whether the transaction committed or rolled back.
*/
/* This dance with casting the NEW and OLD values to a ROW is not necessary in pg 9.0+ */
IF (TG_OP = 'UPDATE') THEN
v_old_data := ROW(OLD.*);
v_new_data := ROW(NEW.*);
INSERT INTO audit.logged_actions (schema_name,table_name,user_name,action,original_data,new_data,query)
VALUES (TG_TABLE_SCHEMA::TEXT,TG_TABLE_NAME::TEXT,session_user::TEXT,substring(TG_OP,1,1),v_old_data,v_new_data, current_query());
RETURN NEW;
ELSIF (TG_OP = 'DELETE') THEN
v_old_data := ROW(OLD.*);
INSERT INTO audit.logged_actions (schema_name,table_name,user_name,action,original_data,query)
VALUES (TG_TABLE_SCHEMA::TEXT,TG_TABLE_NAME::TEXT,session_user::TEXT,substring(TG_OP,1,1),v_old_data, current_query());
RETURN OLD;
ELSIF (TG_OP = 'INSERT') THEN
v_new_data := ROW(NEW.*);
INSERT INTO audit.logged_actions (schema_name,table_name,user_name,action,new_data,query)
VALUES (TG_TABLE_SCHEMA::TEXT,TG_TABLE_NAME::TEXT,session_user::TEXT,substring(TG_OP,1,1),v_new_data, current_query());
RETURN NEW;
ELSE
RAISE WARNING '[AUDIT.IF_MODIFIED_FUNC] - Other action occurred: %, at %',TG_OP,now();
RETURN NULL;
END IF;
EXCEPTION
WHEN data_exception THEN
RAISE WARNING '[AUDIT.IF_MODIFIED_FUNC] - UDF ERROR [DATA EXCEPTION] - SQLSTATE: %, SQLERRM: %',SQLSTATE,SQLERRM;
RETURN NULL;
WHEN unique_violation THEN
RAISE WARNING '[AUDIT.IF_MODIFIED_FUNC] - UDF ERROR [UNIQUE] - SQLSTATE: %, SQLERRM: %',SQLSTATE,SQLERRM;
RETURN NULL;
WHEN OTHERS THEN
RAISE WARNING '[AUDIT.IF_MODIFIED_FUNC] - UDF ERROR [OTHER] - SQLSTATE: %, SQLERRM: %',SQLSTATE,SQLERRM;
RETURN NULL;
END;
$body$
LANGUAGE plpgsql
SECURITY DEFINER
But if you observe in the above function current_query() is not coming with the mentioned language plpgsql. It throws some error. When I googled I found that in order to use current_query() function PL/CTL language must be installed. I tried to install as mentioned below. It throws an error. So kindly help me how to install PL/CTL language into my database so that current_query() function should work
-bash-3.2$ createlang -d dbname pltcl
createlang: language installation failed: ERROR: could not access file "$libdir/pltcl": No such file or directory
Okay as you suggested I created that current_query() function,but this time I got some thing like this , What i did is ,
CREATE TABLE phonebook(phone VARCHAR(32), firstname VARCHAR(32), lastname VARCHAR(32), address VARCHAR(64));
CREATE TRIGGER phonebook_auditt AFTER INSERT OR UPDATE OR DELETE ON phonebook
FOR EACH ROW EXECUTE PROCEDURE audit.if_modified_func();
INSERT INTO phonebook(phone, firstname, lastname, address) VALUES('9966888200', 'John', 'Doe', 'North America');
for testing the function i created a table named phonebook and created a trigger so that the function mentioned above audit.if_modified_func() will be executed after any insert or update or delete.the row is getting inserted but I am getting a error reg the audit.if_modified_func() function .the error is as follows
WARNING: [AUDIT.IF_MODIFIED_FUNC] - UDF ERROR [OTHER] - SQLSTATE: 42703, SQLERRM: column "*" not found in data type phonebook
Query returned successfully: 1 rows affected, 10 ms execution time.
Kindly tell me what can i do to get rid of the above error.
Not sure where you found the information about current_query and pltcl. These are unrelated. The reason why you can't find pltcl is simply because you're using too old PostgreSQL. current_query() has been added to Pg in version 8.4.
Is there any particular reason why you're using such old version? It is no longer supported, and it lacks almost 8 years of added features!
If you have to use 8.1, you might want to define:
create function current_query() returns text as '
select current_query from pg_stat_activity where procpid = pg_backend_pid();
' language sql;
But it is much better idea just to upgrade.
As for edited and added second question - it's very likely that Pg 8.1 cannot use "row.*" construct. Find who wrote the original code with the "dance comments", and ask about it. Perhaps it was meant to work in newer Pgs.