SQL Server catch error from extended stored procedure - c++

Hello I have an extended stored procedure that sends an error message.
srv_sendmsg(pSrvProc, SRV_MSG_ERROR, errorNum, SRV_FATAL_SERVER, 1,
NULL, 0, (DBUSMALLINT) __LINE__,
buff,
SRV_NULLTERM);
I've set the severity to SVR_FATAL_SERVER just as a test to see if I can cause the message to throw an exception in the sql.
In my SQL i'm doing:
BEGIN TRY
EXEC dbo.xp_somethingCool
SET #Error = ##ERROR
END TRY
BEGIN CATCH
PRINT 'AN Error occoured!'
SELECT ERROR_NUMBER() AS ErrorNumber
,ERROR_MESSAGE() AS ErrorMessage;
END CATCH
I would think that when my xp sends the error message the tsql would catch the error and select the error_number and error_message. Instead what ends up happening is that the xp sends the message and the T-SQL continues on its way like nothing happened. The ##Error variable doesn't get set either.
So I was wondering if there was any trick to getting SQL to catch an error from an XP ?
Thanks,
Raul

You can only test the result from an extended stored proc, and use that to throw an exception.
...
EXEC #rtn = dbo.xp_somethingCool
IF #rtn <> 0
RAISERROR ...
...
In very simple terms, an extended stored proc is not SQL run by the database engine so you can't issue RAISERROR. See KB 190987 for some more info

Never raise anything so high. Anything raised with severity above 16 will abort the batch, so your T-SQL catch block never gets a chance to run. Something as high as SVR_FATAL_SERVER will shutdown the server immedeatly.

You should be able to use RAISERROR to throw an exception.
Per comment: Are you not creating your own extended stored proc? If so, you can use throw or do something like 1/0 to throw an exception.

Related

OCI 19c - Parsing a PL/SQL statement that contains SELECT-FROM-INTO statements

I have a need to parse queries using OCI. For the most part - it is working. However I ran into a problem today that I am not able to figure out. For the time being - it looks like it's either a bug in OCI (currently using 19c 32bit) - or for some reason these kinds of statements are being ignored.
Whenever a SQL query contains SELECT-FROM-INTO statements - the entire query is ignored when OCIStmtExecute is invoked with OCI_PARSE_ONLY. It doesn't matter if there are invalid entity names / syntax in the query. I tried to find some additional info online regarding this particular situation - but I found nothing of use.
The query in question is below (the query is intentionally using garbage entity names to illustrate the strange behavior)
BEGIN
SELECT ColumnThatDoesntExist FROM DerpyTable INTO ThisVariableDoesntExist WHERE YeahRight = :BindName;
END
The statement preparation code / execution code is below
...
...
if (OCIStmtPrepare2(connectionHandle
, &statementHandle
, errorHandle
, command
, commandLength
, nullptr
, 0
, OCI_NTV_SYNTAX
, OCI_DEFAULT))
ThrowLastError(__FUNCTIONW__, __FILE__, __LINE__);
...
...
if (OCIStmtExecute(connectionHandle
, statementHandle
, errorHandle
, 0
, 0
, 0, 0, OCI_PARSE_ONLY))
ThrowLastError(__FUNCTIONW__, __FILE__, __LINE__);
In this particular test - OCIStmtExecute should be failing - however OCI_SUCCESS (aka 0) is returned when OCIStmtExecute is invoked. Are there additional flags I should be using for these kind of statements or should I be looking at another approach?
I tried prepending the query with EXPLAIN PLAN FOR and invoke OCIStmtExecute with the default flag - but that just results in a missing-keyword error.
It is not a bug in the OCI the return code OCI_SUCCESS (aka 0) is correct. It sent your statement to to the data base.
Your statement is an anonymous block, indicated by BEGIN, and contains errors. You can do what you want, but you have to define the variable you select into. You have not done that so that would be 1 error. Also the INTO clause comes before the FROM so the statement should be "select...INTO...from", that would be error 2. Finally if it is true the column you select actually does not that will also generate a "compile" time error, that would be error 3. Also I believe EXPLAIN PLAN for an anonymous block, is also invalid, but it been a long time since I ran into it.
But you can try the following:
declare
ThisVariableDoesntExist varchar2(50), -- or the correct data type
begin
select columnthatdoesntexist
into thisvariabledoesntexist
from derpytable
where yeahright = :bindname;
end;
Note: As an anonymous block the above should run (if the column actually exists). However, you will not get output. You may wish to add
dbms_output.put_line('Value=' || ThisVariableDoesntExist);
Oracle object names are not case sensitive and echoed back form Oracle will be folded to upper case, so it bast to avoid CamelCase and instead use snake_case.

GATE_Using for Thesis_Run-time Error

When I am trying to run corpus pipeline on language resources. It is throwing the below (even though I follow the order as Document reset, english tokeniser, sentence splitter)
Can someone help me with the process to debug this run-time error
Error:
gate.creole.ExecutionException: No sentences or tokens to process in document Password_Safe-window1.txt_0003E
Please run a sentence splitter and tokeniser first!
at gate.creole.POSTagger.execute(POSTagger.java:257)
at gate.util.Benchmark.executeWithBenchmarking(Benchmark.java:291)
at gate.creole.SerialController.runComponent(SerialController.java:225)
at gate.creole.SerialController.executeImpl(SerialController.java:157)
at gate.creole.SerialAnalyserController.executeImpl(SerialAnalyserController.java:223)
at gate.creole.SerialAnalyserController.execute(SerialAnalyserController.java:126)
at gate.util.Benchmark.executeWithBenchmarking(Benchmark.java:291)
at gate.gui.SerialControllerEditor$RunAction$1.run(SerialControllerEditor.java:1759)
at java.lang.Thread.run(Thread.java:745)
Edit:
The files are not empty. As i tried to implement #dedek's suggestion, it has thrown no errors. But raised one more problem as follows:
Exception in thread "ApplicationViewer1" java.lang.OutOfMemoryError: Java heap space
I think it is because your document is empty.
Can you confirm that?
There is a run-time param failOnMissingInputAnnotations of the POSTagger, set it to false and it should be ok.
See also the docs:
failOnMissingInputAnnotations - if set to false, the PR will not fail with an ExecutionException if no input Annotations are found and instead only log a single warning message per session and a debug message per document that has no input annotations (run-time, default = true).
Concerning the OutOfMemoryError: Java heap space
See following questions:
Getting OOM while using GATE on large data set
GATE PersistenceManager.loadObjectFromFile outofmemory error while loading .gapp files
JAVA PermGem memory

MariaDB, Syntax error when executing stored procedure in c++ program

First of all, thank you for read this question and apologize for my poor english.
I'm now converting my DB from SQL-Server to MariaDB. I installed MySQL ODBC driver and added 'system DSN'. ( C:\Windows\SysWOW64\odbcad32.exe )
The problem occured at executing a stored procedure.
When I created an procedure in SQLyog, There was no error and execution also runs fine. But When I execute stored procedure in my c++ application syntax error occurs.
Database [MySQL][ODBC 5.3(w) Driver][mysqld-5.5.5-10.0.20-MariaDB]You
have an error in your SQL syntax; check the manual that corresponds to
your MariaDB server version for the right syntax to use near
'get_bookProperty ?' at line 1
My C++ code is...
bool LoadbookProperty::OnExecute(db::IDbProcesser* dbProcesser)
{
const char* bookName = m_bookName.c_str();
dbProcesser->BindParams(bookName);
if (!dbProcesser->Execute("get_bookProperty"))
return false;
char type[PROPERTY_NAME_LEN];
char value[PROPERTY_VALUE_LEN];
dbProcesser->BindCols(type, value);
dbProcesser->FetchWith([this, &type, &value]()
{
m_properties.push_back(std::make_pair(type, value));
});
return true;
}
And my procedure is...
USE bookInfoDB;
-- GetbookProperty
DELIMITER ;;
CREATE PROCEDURE get_bookProperty (
IN pi_bookName VARCHAR(32)
)
this_proc:BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
END;
SELECT bookName, bookPrice FROM bookProperty WHERE bookName = pi_bookName;
END ;;
DELIMITER ;
I really don't know what's the matter. Please help me.
Solved it! The cause is EXECUTION function. When my team used SQL Server, EXECUTION function's string combination was EXEC and no bracket.
(As you all know, SQL Server execute procedure by 'EXEC sp_name arg1 arg2 ...')
But MySQL(and also MariaDB)'s procedure execution syntax is 'CALL sp_name (arg1, arg2 ...). Our programmer have changed EXECTION function's string combination. And? It works perfectly!

Exception handling in Protocol Buffers C++

I don't find anything in Protocol Buffers documentation for exception handling in C++. In Javadoc it has clearly defined ones like InvalidProtocolBufferException, but not in C++.
Sometimes I ran my program and it crashes when it finds missing fields in what it thinks a valid message, then it simply stops and throws errors like this:
[libprotobuf FATAL google/protobuf/message_lite.cc:273] CHECK failed:
IsInitialized(): Can't serialize message of type "XXX" because it is
missing required fields: YY, ZZ
unknown file: Failure
C++ exception with description "CHECK failed: IsInitialized(): Can't
serialize message of type "XXX" because it is missing required fields:
YY, ZZ" thrown in the test body.
The source code of message_lite.cc all wrapped around with "GOOGLE_DCHECK" or "InitializationErrorMessage"...
My application does not allow exceptions like this to halt the program (not sure what the term is in C++ but basically no UncheckedExceptions), so I really need a way to catch these, log errors, and return gracefully, in case some messages got severely corrupted. Is there anyway doing that? Why do I see this post indicating some sort of google::protobuf::FatalException but I couldn't find documentations around it (only FatalException probably not enough also).
Thanks!
The failure you are seeing indicates that there is a bug in your program -- the program has requested to serialize a message without having filled in all the required fields first. Think of this like a segmentation fault. You shouldn't try to catch this exception -- you should instead fix your app so that the exception never happens in the first place.
Note that the check is a DCHECK, meaning it is only checked in debug builds. In your release builds (when NDEBUG is defined), this check will be skipped and the message will be written even though it is not valid. So, you don't have to worry about this crashing your application in production, only while debugging.
(Technically you could catch google::protobuf::FatalException, but the Protobuf code was not originally designed to be exception-safe. Originally, check failures would simply abort the program. It looks like FatalException was added recently, but since the code is not exception-safe, it's likely that you'll have memory leaks any time a FatalException is thrown. So, you probably should treat it like an abort().)
I solved that
my problem was same you.
if another thread change size of proto item while you do serialization then FatalException throw
then at first I copy that in another proto item then I do serialize that.
ProtoInput item; // it is global object
.
.
.
fstream output("myfile",
ios::out | ios::trunc | ios::binary);
ProtoInput in;
in.CopyFrom(item);
size_t size = in.ByteSizeLong();
void *buffer = malloc(size);
if (in.SerializeToArray(buffer, size) == true) {
output.write((char *) buffer, size);
}
output.close();
free(buffer);

GetLastError() Returns 'ERROR_NO_MORE_FILES' (18) after attempting to create a registry key

I have the following code, attempting to allow the program to run at startup:
HKEY key;
if(RegOpenKey(HKEY_CURRENT_USER,LPCWSTR("Software\\Microsoft\\Windows\\CurrentVersion\\Run"),&key) != ERROR_SUCCESS) {
std::cout<<"Unable to open Reg key last error - "<<GetLastError()<<"\n";
system("pause");
}
Omitting the parts that aren't necessary. It prints that there was an error creating the registry key with the error code 18, which according to this page means that I'm encountering an error that returns ERROR_NO_MORE_FILES. Unfortunately the description says the same thing and I don't know what this means in the case of creating a registry key. I have tried running the program as an administrator, the key does not already exist either. Thanks.
If you read the documentation, it states:
Return value
"If the function succeeds, the return value is ERROR_SUCCESS.
If the function fails, the return value is a nonzero error code defined in Winerror.h. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error."
It does not state to call GetLastError(). Also, this has nothing to do with C++.
Your error checking is wrong. Registry API functions return error codes. They don't use SetLastError. You have to use the error code returned by the function to diagnose errors.
The obvious error in your code is the cast to wide text. That does not change the fact that your string is actually 8 bit text. Use the L prefix.
L"Software\\Microsoft\\Windows\\CurrentVersion\\Run"
For what it is worth, you should use RegOpenKeyEx to open keys rather than RegOpenKey. And for creating keys use RegCreateKeyEx.
I had the same result (GetLastError() returned ERROR_NO_MORE_FILES) when trying to call RegCreateKeyEx() on a registry key where the running process had insufficient rights (in my case "HKLM\SYSTEM\CurrentControlSet\Services\Eventlog\Application"). When starting the process with elevated privileges it succeeded.
So maybe there could be a connection between error code 18 and UAC.