SQLExecDirect failed but SQLGetDiagRec has no data - error-handling

I'm trying to setup some useful error handling in a program that used ODBC. According to documentation if SQLExecDirect returns SQL_ERROR I should be able to call SQLGetDiagRec to get SQL_STATE and possibly some messages, but in my tests when I call SQLGetDiagRec right after getting an error from SQLExecDirect I get SQL_NO_DATA returned and no information.
Code:
result = SQLExecDirect(hstmt, <SQL Statement>, SQL_NTS);
if(result == SQL_ERROR)
{
SQLSMALLINT msg_len = 0;
SQLCHAR sql_state[6], message[256];
SQLINTEGER native_error = 0;
result = SQLGetDiagRec(SQL_HANDLE_DBC, hDbc, 1, sql_state, &native_error, message, countof(message), &msg_len);
// Here 'result' is SQL_NO_DATA
....
}
It works in other cases, just not for SQLExecDirect for some reason. I'm also aware that one should cycle through the SQLGetDiagRec results, but if the very first one returns SQL_NO_DATA, according to documentation it means that there are no further ones.
The specific error that I was testing it with was requesting a non-existent table.
Is there anything else that I need to do in order obtain at least an error code, or does the diagnostic not work for errors that result from incorrect SQL requests?

When you call SQLGetDiagRec, pass SQL_HANDLE_STMT and your statement handle (hstmt in your example). That should return errors associated with that specific statement.

Related

ERROR: Limit set by ERRORS= option reached. Further errors for this INPUT function will not be printed

While using the code able I'm getting an error message as below and also I'm getting the output table.
input(put(serv_to_DT_KEY,8.),yymmdd8.)
between datepart(D.throughdate)
and datepart(intnx('day',d.throughdate,31))
Error: INPUT function reported 'ERROR: Invalid date value' while processing WHERE clause.
ERROR: Limit set by ERRORS= option reached. Further errors for this INPUT function will not be printed.
Could you please help
It's not a true error, exactly; it's a data error, which SAS will let by. What it's saying is the value in serv_to_DT_KEY is not a valid yymmdd8 for some records. (The rest of the message, about "limit set by ...", is just SAS saying it's only going to tell you about 20 or so individual data errors instead of showing you every single one, so your log isn't hopeless.)
To fix this you have several options:
If there is a data issue [ie, all rows should have a valid date], then fix that.
If it's okay that some rows don't have a valid date (for example, they might have a missing), you can use the ?? modifier in the informat in input to tell it to ignore these.
Like this:
input(put(serv_to_DT_KEY,8.),?yymmdd8.)
between datepart(D.throughdate)
and datepart(intnx('day',d.throughdate,31))

make SQL query fail on condition

For XYZ reason I need a query to explicitly fail (return error code to connection) if some condition is met (on Snowflake).
Can someone recommend an approach?
Some illustration in pseudo-code:
IF 0= ( SELECT COUNT(*) FROM XYZ) THEN FAIL
I like Simeon's approach, but you may want a custom error message if this is running in a long script. Throwing an error in a JavaScript UDF will allow custom (if untidy) error messages:
create or replace function RAISE_ERROR(MESSAGE string)
returns string
language javascript
as
$$
throw "-->" + MESSAGE + "<--";
$$;
select
case (select count(*) from XYZ)
when 0 then raise_error('My custom error.')
else 'There are rows in the table'
end
;
If there are no rows in XYZ, it will generate an error message that reads:
JavaScript execution error: Uncaught --> My custom error <--. in RAISE_ERROR at '
throw MESSAGE;' position 4 stackstrace: RAISE_ERROR line: 2
It's not the tidiest of error messages, but it will allow you to embed a custom error message if you need help identifying the error. The arrows should help direct people to the real error message thrown in the stack.
SELECT IFF(true, 1::number, (1/0)::number);
then:
IFF(TRUE, 1::NUMBER, (1/0)::NUMBER)
1
where-as
SELECT IFF(false, 1::number, (1/0)::number);
gives:
Division by zero

Issue raising an error in after trigger

I'm having an issue raising an error in an after trigger, and I don't see any reason why I can raise an error one way, but not the other. Let me give you an example.
The following trigger will fail and raise the following error:
Error:Apex trigger tstTrigger2 caused an unexpected exception, contact
your administrator: tstTrigger2 : execution of AfterUpdate caused by:
System.FinalException: SObject row does not allow errors:
Trigger.tstTrigger2 : line 19, column 1
trigger tstTrigger2 on Account (after update)
{
Set<Id> AccountIds = Trigger.newMap.keySet();
List<Account > accountsToProcess = [Select Id, Name from Account Where Id IN : AccountIds];
for(Account act: accountsToProcess)
{
act.addError('doesn't work');
}
}
However, raising an error this way works. Please note there is always ever only 1 record in the keyset, at least in this test scenario.
trigger tstTrigger on Account (after update)
{
Set<Id> AccountIds = Trigger.newMap.keySet();
List<Account > accountsToProcess = [Select Id, Name from Account Where Id IN : AccountIds];
Trigger.new[0].addError('However, this works?');
}
Any explanation of why the first one is failing, and the second one is not is greatly appreciated. As well, if you could point me to the best way to implement this so that it's bulkified that would be great. Thanks!
addError() doesn't roll back your insertion it will just prevent the further execution of the script, so the data is never inserted if an you throw an error on UI.
By doing this
Trigger.new[0].addError('However, this works?');
You're simply throwing an error on the first record in the list thereby stopping anything processing.
Something like this will solve your first code snip
trigger tstTrigger2 on Account (after update)
{
Map<ID, Account> accountMap = Trigger.newMap;
for(ID act: accountMap.keySet())
{
accountMap.get(act).addError('doesnt work');
}
}
You were querying out the account Ids and by that time they were already committed to the database, which won't allow errors to be flagged on the records

Yii CDbException.. invalid input syntax for integer: "1,075"

I started receiving this error from a production site since this morning and I'm wondering why I don't get the same in UAT or the developer environment..
Is any one familiar with an error like this ?
CDbException
Description
CDbCommand failed to execute the SQL statement: SQLSTATE[22P02]: Invalid text representation: 7 ERROR: invalid input syntax for integer: "1,076"
Source File
C:\inetpub\wwwroot\framework1.0\db\CDbCommand.php(372)
00360: }
00361:
00362: if($this->_connection->enableProfiling)
00363: Yii::endProfile('system.db.CDbCommand.query('.$this->getText().')','system.db.CDbCommand.query');
00364:
00365: return $result;
00366: }
00367: catch(Exception $e)
00368: {
00369: if($this->_connection->enableProfiling)
00370: Yii::endProfile('system.db.CDbCommand.query('.$this->getText().')','system.db.CDbCommand.query');
00371: Yii::log('Error in querying SQL: '.$this->getText().$par,CLogger::LEVEL_ERROR,'system.db.CDbCommand');
00372: throw new CDbException(Yii::t('yii','CDbCommand failed to execute the SQL statement: {error}',
00373: array('{error}'=>$e->getMessage())));
00374: }
00375: }
00376: }
Attached a screenshot too.. the application is based on yii framework and postgress database.
Quick reply is highly appreciated.
The issue was actually because used number_format() function to a primary key and later in a code section it inputs the formatted number to search query.. i.e select * from user where id = 1,075 (instead of id = 1075)
Changing the number_format() function to apply only on selected areas worked.

SQL STATE 37000 [Microsoft][ODBC Microsoft Access Driver] Syntax Error or Access Violation

Good day!
I get this error:
SQL STATE 37000 [Microsoft][ODBC Microsoft Access Driver] Syntax Error
or Access Violation, when trying to run an embedded SQL statement on
Powerscript.
I am using MsSQL Server 2008 and PowerBuilder 10.5, the OS is Windows 7. I was able to determine one of the queries that is causing the problem:
SELECT top 1 CONVERT(DATETIME,:ls_datetime)
into :ldtme_datetime
from employee_information
USING SQLCA;
if SQLCA.SQLCODE = -1 then
Messagebox('SQL ERROR',SQLCA.SQLERRTEXT)
return -1
end if
I was able to come up with a solution to this by just using the datetime() function of PowerBuilder. But there are other parts of the program that is causing this and I am having a hard time in identifying which part of the program causes this. I find this very weird because I am running the same scripts here in my dev-pc with no problems at all, but when trying to run the program on my client's workstation I am getting this error. I haven't found any differences in the workstation and my dev-pc. I also tried following the instructions here, but the problem still occurs.
UPDATE: I was able to identify the other script that is causing the problem:
/////////////////////////////////////////////////////////////////////////////
// f_datediff
// Computes the time difference (in number of minutes) between adtme_datefrom and adtme_dateto
////////////////////////////
decimal ld_time_diff
SELECT top 1 DATEDIFF(MINUTE,:adtme_datefrom,:adtme_dateto)
into :ld_time_diff
FROM EMPLOYEE_INFORMATION
USING SQLCA;
if SQLCA.SQLCODE = -1 then
Messagebox('SQL ERROR',SQLCA.SQLERRTEXT)
return -1
end if
return ld_time_diff
Seems like passing datetime variables causes the error above. Other scripts are working fine.
Create a transaction user object inherited trom transaction.
Put logic in the sqlpreview of your object to capture and log the sql statement being sent to the db.
Instantiate it, connect to the db, and use it in your embedded sql.
Assuming the user gets the error you can then check what was being sent to the db and go from there.
The error in your first statement should be the second parameter to CONVERT function.
It's type is not a string, it's type is an valid expression
https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql
So I would expect that your
CONVERT(DATETIME,:ls_datetime)
would evaluate to
CONVERT(DATETIME, 'ls_datetime')
but it should be
CONVERT(DATETIME, DateTimeColumn)
The error in your second statement could be that you're providing an wrong datetime format.
So please check if your error still occurs when you use this function
https://learn.microsoft.com/en-us/sql/t-sql/statements/set-dateformat-transact-sql
with the correct datetime format you're using