How to make a SQL Server agent job step failure on purpose - sql-server

I have a process and the first step is to check status of other process. If the other process is done I would want to run the rest steps and if not I would want to quit the job.
I have a table that looks into the status and if all done it will mark as 'done'. So what should I put in the first step so that when the status is not 'done', it makes step 1 fail?

There are lots of ways you can force sql-server to throw (or raise) an error but I would recommend using THROW for SQL-Server 2012 + or RAISERROR below that as that is your actual intention. So you could do something like:
IF EXISTS(SELECT * FROM StatusTable WHERE status <> 'done')
BEGIN
;THROW 51000, 'Process Is Not Finished', 1
END

You can use also "Select 1/0" this will parse but it will giving error while execution

I feel it is bad practice to fail a job-step to implement application logic. Better to use IF (some condition) THEN (some job-step action) ELSE (print an explanation why there was no job-step action). And reserve failures for operational issues.

Related

Multi-Threaded VB.net: Update then return row id?

I'm trying to code a multi-threaded program using VB.NET. It's a simple program: go to a database, get a row, process some back-end, then update the row and set it as "processed = true". Because there is so much data, I'm planning to do a multi-threaded program for it.
SELECT... FOR UPDATE doesn't seem to work in a transaction for some odd reason, and so I've decided to pre-emptively mark the row as "being read = TRUE", then process it from there.
Is it possible to update the row, then retrieve the row ID from the same SQL statement?
I've tried using these SQL statements together:
Dim sqlUpdateStatement As String = "SET #uid := 0;UPDATE process_data SET reading = TRUE, idprocess_data = (SELECT #uid := idcrawl_data) WHERE reading IS NOT TRUE AND processed IS NOT TRUE LIMIT 1;SELECT #uid;"
but it tells me that there was a fatal error encountered during command execution.
Any ideas?
EDIT
After some testing, I've come to the conclusion that you can't use MySQL variables when performing updates in VB.Net. Is this true? And if so, is there a workaround?
I eventually took the time to debug the SELECT FOR UPDATE portion of my code to get it to work on a Transaction basis. Thanks everyone for their time!

When do a PREPARE QUERY fails in PRO C?

When do a PREPARE QUERY fails in PRO C?
EXEC SQL AT :db_id PREPARE QUERY FROM :sql_query;
bool sql_status = (sqlca.sqlcode == OERR_ORACLE_SUCCESS);
if (sql_status)
{
}
else
{
}
I don't have this problem until recently, The code was working fine the PREPARE QUERY is working fine (going into if loop_, but all of a sudden it failed, and is not working after that (going into else loop).
Nothing has changed and it's the same binary.
Does anybody face a similar problem in the past?
I've written a LOT of pro*c in the past, and over time realized that you don't want to be checking the return code of the PREPARE statement as it never returns any value. Here is what I mean:
The PREPARE sqlca.sqlcode value is the return code of the statement that ran immediately BEFORE the PREPARE statement. In other words, if you check the output of the PREPARE statement and the statement that executed right before the PREPARE statement fails, then the return code of the prepare is failed. If the previous statement succeeded, then the PREPARE appears to have succeeded.
In other words, the prepare sqlca.sqlcode value is basically nothing (it doesn't ever fail on its own). So if the PREPARE is now failing, check the statement that executed right before the PREPARE statement and ensure you're checking the sqlca.sqlcode value of that one. My bet is that the previous statement is failing, and the error returned relates to that statement. Make sense?
-Jim

SQL Injection, ignore first select command

I am trying to build a scenario that would allow me to expose additional data from a server (for case-demo purposes). The server calls a vulnerable SQL code:
EXEC my_storeProc '12345'
where "12345" (not the single quotes) is the parameter. This performs a SELECT statement. I would like to eliminate this execution and instead call my own select statement, however the server side code will only accept the first select statement called, contained within the aforementioned EXEC call. Calling the second statement is easy:
EXEC my_storeProc '12345 ' select * from MySecondTable--
(the -- at the end will block the closing single quote added by the server to prevent errors). My problem is that although there are 2 select statements, the server will only parse the first one. Is there a way to cancel the first EXEC call without throwing an error so that the second one would be taken instead? Perhaps even a UNION but there isn't much I can do with only one variable open to exploit (variable being 12345 in this case).
You have to think of how it will be executed, specifically you want it called so it doesn't raise an exception and put the kabosh on the whole statement. You can't set the result to always true with a proc call, so there is no real way escape the proc. Instead, you'll want to slip a second command in, Your desired code looks like;
exec my_Storeproc '1234'; select * from mysecondtable
So we need to close the quotes, and make a new statement. That would mean the string with the insert needs to be;
1234'; select * from mysecondtable where 1 = '1
There is a flaw in this, whatever command you are executing is not being returned to the UI. To get the data you'll have to add a server connection to the second command.
To make the second command unnecessary you would have to inject code into the proc, which is a non starter since the proc is already complied and sql injection relies on confusing the compiler as to what is data and what is commands. For a more verbose explanation of that check out this answer:
https://security.stackexchange.com/a/25710

SQL Server --- using raiserror without status accident

I wanted to user RAISERROR in my SQL-Server codes but I noticed that some status code have interruption with built-in SQL Error statuses...
for example status code "1" is used for "Devide By Zero Error", And I dont wanna use it any more...
now I want to see what status codes are safe to use withour interruption ?
If you want to use your own msgid use a value of greater then 50000. The values below 50000 are reserved for built in messages. To see the list of existing messages you can do a 'select * from sys.messages'. 50000 is used when a value for msgid is not provided.

PRINT statement in T-SQL

Why does the PRINT statement in T-SQL seem to only sometimes work? What are the constraints on using it? It seems sometimes if a result set is generated, it becomes a null function, I assumed to prevent corrupting the resultset, but could it's output not go out in another result set, such as the row count?
So, if you have a statement something like the following, you're saying that you get no 'print' result?
select * from sysobjects
PRINT 'Just selected * from sysobjects'
If you're using SQL Query Analyzer, you'll see that there are two tabs down at the bottom, one of which is "Messages" and that's where the 'print' statements will show up.
If you're concerned about the timing of seeing the print statements, you may want to try using something like
raiserror ('My Print Statement', 10,1) with nowait
This will give you the message immediately as the statement is reached, rather than buffering the output, as the Query Analyzer will do under most conditions.
The Print statement in TSQL is a misunderstood creature, probably because of its name. It actually sends a message to the error/message-handling mechanism that then transfers it to the calling application. PRINT is pretty dumb. You can only send 8000 characters (4000 unicode chars). You can send a literal string, a string variable (varchar or char) or a string expression. If you use RAISERROR, then you are limited to a string of just 2,044 characters. However, it is much easier to use it to send information to the calling application since it calls a formatting function similar to the old printf in the standard C library. RAISERROR can also specify an error number, a severity, and a state code in addition to the text message, and it can also be used to return user-defined messages created using the sp_addmessage system stored procedure. You can also force the messages to be logged.
Your error-handling routines won’t be any good for receiving messages, despite messages and errors being so similar. The technique varies, of course, according to the actual way you connect to the database (OLBC, OLEDB etc). In order to receive and deal with messages from the SQL Server Database Engine, when you’re using System.Data.SQLClient, you’ll need to create a SqlInfoMessageEventHandler delegate, identifying the method that handles the event, to listen for the InfoMessage event on the SqlConnection class. You’ll find that message-context information such as severity and state are passed as arguments to the callback, because from the system perspective, these messages are just like errors.
It is always a good idea to have a way of getting these messages in your application, even if you are just spooling to a file, because there is always going to be a use for them when you are trying to chase a really obscure problem. However, I can’t think I’d want the end users to ever see them unless you can reserve an informational level that displays stuff in the application.
Query Analyzer buffers messages. The PRINT and RAISERROR statements both use this buffer, but the RAISERROR statement has a WITH NOWAIT option. To print a message immediately use the following:
RAISERROR ('Your message', 0, 1) WITH NOWAIT
RAISERROR will only display 400 characters of your message and uses a syntax similar to the C printf function for formatting text.
Please note that the use of RAISERROR with the WITH NOWAIT option will flush the message buffer, so all previously buffered information will be output also.
I recently ran into this, and it ended up being because I had a convert statement on a null variable. Since that was causing errors, the entire print statement was rendering as null, and not printing at all.
Example - This will fail:
declare #myID int=null
print 'First Statement: ' + convert(varchar(4), #myID)
Example - This will print:
declare #myID int=null
print 'Second Statement: ' + coalesce(Convert(varchar(4), #myID),'#myID is null')
For the benefit of anyone else reading this question that really is missing print statements from their output, there actually are cases where the print executes but is not returned to the client. I can't tell you specifically what they are. I can tell you that if you put a go statement immediately before and after any print statement, you will see if it is executed.
Do you have variables that are associated with these print statements been output? if so, I have found that if the variable has no value then the print statement will not be ouput.

Resources