I have stored procedure that calls a sql job but the job is failing if 2 users make a call to the stored procedure at the same time so here is what I want to do:
check if sql job is running first
only execute the 2nd call if the first call finishes.
I have seen some examples where you can find out if job is running but can't seem to find out to put the 2nd call on hold and only execute when the first one completes.
DECLARE #job_name NVARCHAR(MAX) = 'mySQLJob'
EXEC msdb.dbo.sp_start_job #job_name = #mySQLJob
the error I am getting is something like "job is already running"
sp_help_job can give you this information
EXEC msdb..sp_help_job #job_name = 'mySQLJob', #job_aspect = 'JOB'
current_execution_status Values
- 1 Executing
- 2 Waiting For Thread
- 3 Between Retries
- 4 Idle
- 5 Suspended
- 6 Obsolete
- 7 PerformingCompletionActions
Related
I am having a fully running procedure on snowflake with no errors at all when calling it:
call ADD_MONTHLY_OBSERVATION_VALUES('#test_azure_blob_stg/Monthly_Report.csv', 'GENERIC_CSV_FORMAT');
I wanted to wrap this command into a task and schedule it to a specific time like so:
CREATE OR REPLACE TASK ADD_MONTHLY_OBSERVATION_VALUES_TASK
WAREHOUSE = 'DEV_WH'
TIMESTAMP_INPUT_FORMAT = 'YYYY-MM-DD HH24'
//SCHEDULE = 'USING CRON 0 6-7 * * SUN,MON,TUE,WED,THU Asia/Dacca'
//Schedule for each minute
SCHEDULE = 'USING CRON * * * * * UTC'
AS
call ADD_MONTHLY_OBSERVATION_VALUES('#test_azure_blob_stg/Monthly_Report.csv', 'GENERIC_CSV_FORMAT');
And then I resumed the task to work:
ALTER TASK ADD_MONTHLY_OBSERVATION_VALUES_TASK RESUME;
When I checked the history of the task:
STATE: SUCCEEDED
ERROR_CODE: NULL
ERROR_MESSAGE: NULL
QUERY_START_TIME: 2021-01-27 16:00:06.198 -0800
COMPLETED_TIME: 2021-01-27 16:00:24.902 -0800
RETURN_VALUE: NULL
Actually the procedure will return a string DONE when everything have been successfully added/updated.
When running:
show tasks;
The procedure's state is started.
Why the procedure is not being executed when called using a task?
There was new data uploaded to the staged file from Azure, so the procedure should detect the new submissions and start the insert process.
If you run the procedure outside the task, you have to use the task owner role to ensure correct testing. If your procedure works outside the task with task owner privileges, it should also work within the task.
So... I assume there is a problem with your access/rights management. SQL statements executed by the task can only operate on Snowflake objects on which the role has the required privileges. --> You have to grant more privileges on the objects within your procedure to your task owner role.
See more here: https://docs.snowflake.com/en/sql-reference/sql/create-task.html
I'm also new to DevOps, but let me see if I can explain my situation, also if anyone has any advice on doing post deployment scripts and can share their experiences I will be most grateful.
I use SQL Source control from Redgate, Git and Azure DevOps. I have managed to get the build and deployment working perfectly. Additionally we would like to make some data changes so we have additional (Data Change) scripts we wish to run. Linking these tables as static data is not an option as we would end up having most tables linked and end up with extremely timeous build and deploy times.
The script inserts data to a table, thereby triggering the insert trigger which calls a procedure to write to an audit table. The actual error from the deployment log is:
Task : DbUp Migration
2021-01-25T12:52:17.2629353Z Description : Runs SQL Server change scripts, and only those which have not been run already.
2021-01-25T12:52:17.2629405Z Version : 2.1.4
2021-01-25T12:52:17.2629671Z Author : Johan Classon
2021-01-25T12:52:17.2629721Z Help : [More Information](https://github.com/johanclasson/vso-agent-tasks)
2021-01-25T12:52:17.2629775Z ==============================================================================
2021-01-25T12:52:19.6610608Z Beginning database upgrade
2021-01-25T12:52:19.6689401Z Checking whether journal table exists..
2021-01-25T12:52:19.6728756Z Journal table does not exist
2021-01-25T12:52:19.7775348Z Executing Database Server script '001 - EX27605 - rdl.sql'
2021-01-25T12:52:19.7908913Z Checking whether journal table exists..
2021-01-25T12:52:19.7929056Z Creating the [dbo].[_SchemaVersions] table
2021-01-25T12:52:19.8077238Z The [dbo].[_SchemaVersions] table has been created
2021-01-25T12:52:20.2264323Z ifExists - rdl_Rule_Definition_Lookup - rdl_Code = "9900226e"
2021-01-25T12:52:20.2277308Z insert - rdl_Rule_Definition_Lookup - rdl_Code = "9900226e"
2021-01-25T12:52:20.2805780Z SQL exception has occured in script: '001 - EX27605 - rdl.sql'
2021-01-25T12:52:20.2942912Z ##[error]Script block number: 0; Block line 74; Message: Trig_After_Ins_Upd_Del_rdl_Rule_Definition_Lookup
2021-01-25T12:52:20.4528752Z ##[error]System.Data.SqlClient.SqlException (0x80131904): p_dte_Audit_Backend: (Line: 108) [dte_admin]
So the 1st error refers to line 74 of the trigger, if I read this correctly which is a commit on a procedure call to write to the audit table, line 108 of my procedure sets the userID:
DECLARE #user VARCHAR(40)
SET #user =
CASE
WHEN suser_sname() = 'NT SERVICE\SQLAgent$'+##servicename THEN 'dte_admin'
WHEN suser_sname() = 'NT SERVICE\SQLSERVERAGENT' THEN 'dte_admin'
ELSE suser_sname()
END
--###############
select #udt_Audit = udt_Audit
from udt_User_Detail (nolock)
where udt_User_Id = #user--suser_sname()
--select #udt_Audit = udt_Audit from udt_User_Detail
--where udt_User_Id = suser_sname()
if ##rowcount = 0
begin
declare #udt_User_Id varchar(30)
set #udt_User_Id = suser_sname()
The last line being line 108.
Important to note that dte_admin is a login on the SQL Server, it is a sysadmin account and mapped to the database, the dte_admin user is also a user at database level and exists as a user in my user table udt_user_detail.
During the build and deployment I am using variables and they are set to dte_admin username and password.
My question is then, why does this fail with this user?
Deployment Pipeline result
I want to know what happens when a procedure is executed through a job and before it finishes is time for the job to call the next execution of the procedure. Here the job I created:
DECLARE
X NUMBER;
BEGIN
SYS.DBMS_JOB.SUBMIT
(
job => x
,what => 'BEGIN PKG_DISTRIBUIDOR_SCHEDULER.PRC_DISTRIBUYE_TRANSACCIONES(5000); END;'
,next_date => to_date(sysdate,'dd/mm/yyyy hh24:mi:ss')
,interval => 'SYSDATE+30/86400'
,no_parse => FALSE
);
DBMS_OUTPUT.PUT_LINE('Job Number is: ' || to_char(x));
COMMIT;
END;
As you can see, the job is executed each 30 seconds. So if my procedure (PRC_DISTRIBUYE_TRANSACCIONES) delays more than 30 seconds, what does the job do in this case?
If you use the (old deprecated) Jobs, i.e. DBMS_JOB
The starting time for the next execution is determined when the current jobs is finished.
If you specify an interval as SYSDATE+30/86400 then it does not mean: "The job runs every 30 seconds."
It means: "The next jobs starts 30 seconds after the previous job has been finished."
If you use the Scheduler Jobs, i.e. DBMS_SCHEDULER
Immediately after a job starts, the repeat_interval (e.g. FREQ=SECONDLY;INTERVAL=30) is evaluated to determine the next scheduled execution time of the job. While this might arrive while the job is still running, a new instance of the job does not start until the current one completes. See About Setting the Repeat Interval
So it means: If a jobs last longer than 30 seconds then the new job will start immediately after the previous job has been finished.
Nothing happens!
Only when anonymous PL/SQL block inside "what" parameter finish is the next date calculated according the interval parameter
I have a strange issue with msdb.dbo.sp_send_dbmailwithin a stored procedure (code simplified):
SET NOCOUNT ON;
SET XACT_ABORT ON;
-- ...
SET #msg = N'...';
SET #filename = N'...';
EXEC msdb.dbo.sp_send_dbmail
#recipients = 'mailaddr#example.com'
, #blind_copy_recipients = 'another_mailaddr#example.com'
, #from_address = 'senders_mail#example.com'
, #subject = N'...'
, #body = #msg
, #query = N'SET NOCOUNT ON; SELECT <something> FROM <a_view>;'
, #execute_query_database = N'<same database the proc resides in>'
, #query_result_width = 8000
, #attach_query_result_as_file = 1
, #query_attachment_filename = #filename
, #query_result_header = 1
, #query_result_separator = ';'
, #query_result_no_padding = 1
, #exclude_query_output = 1;
I have a database user which is member of db_datareaderand EXECUTEpermissions for the stored procedure. Furthermore the assigned server login is mapped to msdband a member of the DatabaseMailUserRole. There is only 1 single mail profile which is public and flagged as default.
Everything works fine from SSMS: connect with the user's credentials and execute the stored procedure. Great!
The first oddity: if I'm logged in as sysadmin and try to EXECUTE AS it doesn't work. Okay, I found something that points out that there are issues with this.
But the main issue is this: I call the procedure from a 3rd party Java application which connects using the jTDS driver (don't know if this is important). The applicaton executes the procedure ... and nothing else happened (no log entries, the task freezes).
In the activity monitor I see the following:
Process <...>
Database master (??? I've never connected to this
db!)
Task State Running
Wait Type PREEMPTIVE_OS_GETPROCADDRESS
Head Blocker 1
To make things worse I cannot kill this process. If I try this the Command column in the activity monitor shows only KILLED/ROLLBACK.
KILL <PROCESS-ID>shows
spid <...>: Transaction rollback in progress. Estimated rollback completion: 0% Estimated time left: 0 seconds.
I have to restart the whole instance to get rid of the process.
What is happening here?
Finally I found the answer here: blocking from xp_sysmail_format_query waittype of preemptive_os_getprocaddress
It seems that the Java application opens a transaction explicitly (there are 2 calls to stored procedures consecutively). After setting the Auto-Commit option of the database adapter to on everything work's fine.
Essentially I have a job which runs in BIDS and as as a stand lone package and while it runs under the SQL Server Agent it doesn't complete properly (no error messages though).
The job steps are:
1) Delete all rows from table;
2) Use For each loop to fill up table from Excel spreasheets;
3) Clean up table.
I've tried this MS page (steps 1 & 2), didn't see any need to start changing from Server side security.
Also SQLServerCentral.com for this page, no resolution.
How can I get error logging or a fix?
Note I've reposted this from Server Fault as it's one of those questions that's not pure admin or programming.
I have logged in as the proxy account I'm running this under, and the job runs stand alone but complains that the Excel tables are empty?
Here's how I managed tracking "returned state" from an SSIS package called via a SQL Agent job. If we're lucky, some of this may apply to your system.
Job calls a stored procedure
Procedure builds a DTEXEC call (with a dozen or more parameters)
Procedure calls xp_cmdshell, with the call as a parameter (#Command)
SSIS package runs
"local" SSIS variable is initialized to 1
If an error is raised, SSIS "flow" passes to a step that sets that local variable to 0
In a final step, use Expressions to set SSIS property "ForceExecutionResult" to that local variable (1 = Success, 0 = Failure)
Full form of the SSIS call stores the returned value like so:
EXECUTE #ReturnValue = master.dbo.xp_cmdshell #Command
...and then it gets messy, as you can get a host of values returned from SSIS . I logged actions and activity in a DB table while going through the SSIS steps and consult that to try to work things out (which is where #Description below comes from). Here's the relevant code and comments:
-- Evaluate the DTEXEC return code
SET #Message = case
when #ReturnValue = 1 and #Description <> 'SSIS Package' then 'SSIS Package execution was stopped or interrupted before it completed'
when #ReturnValue in (0,1) then '' -- Package success or failure is logged within the package
when #ReturnValue = 3 then 'DTEXEC exit code 3, package interrupted'
when #ReturnValue in (4,5,6) then 'DTEXEC exit code ' + cast(#Returnvalue as varchar(10)) + ', package could not be run'
else 'DTEXEC exit code ' + isnull(cast(#Returnvalue as varchar(10)), '<NULL>') + ' is an unknown and unanticipated value'
end
-- Oddball case: if cmd.exe process is killed, return value is 1, but process will continue anyway
-- and could finish 100% succesfully... and #ReturnValue will equal 1. If you can figure out how,
-- write a check for this in here.
That last references the "what if, while SSIS is running, some admin joker kills the CMD session (from, say, taskmanager) because the process is running too long" situation. We've never had it happen--that I know of--but they were uber-paranoid when I was writing this so I had to look into it...
Why not use logging built into SSIS? We send our logs toa database table and then parse them out to another table in amore user friendly format and can see every step of everypackage that was run. And every error.
I did fix this eventually, thanks for the suggestions.
Basically I logged into Windows with the proxy user account I was running and started to see errors like:
"The For each file enumerator is empty"
I copied the project files across and started testing, it turned out that I'd still left a file path (N:/) in the properties of the For Each loop box, although I'd changed the connection properties. Easier once you've got error conditions to work with. I also had to recreate the variable mapping.
No wonder people just recreate the whole package.
Now fixed and working!