I am running a database and trying to do all data handling through PS/SQL, and the thing is that once I establish the connection, I have this code, but it fails with the error of
SQLException:Invalid SQL type: sqlKind = UNINITIALIZED
The reason why I am executing it in java is because my assignment tells me that java will handle some things (that I haven't included here), but as for everything else (data manipulation and error checking), it must be handled by oracle. Honestly this harsh restriction sounds silly to me.
The intent of the code below is to read user input via an anonymous block and then print it to the DBMS output, though I'm not sure if that is even possible.
Can anyone help me to fix this?
try {
CallableStatement cs = dbConnection.prepareCall("" +
"DECLARE" +
"myMessage varchar2 (20);" +
"BEGIN" +
"myMessage := '&myMessage';" +
"DBMS_OUTPUT.PUT_LINE(myMessage);" +
"END;");
cs.execute();
} catch (SQLException x) {
System.out.println("SQLException:" + x.getMessage());
}
Related
Queries are read fine when debugging only My Code. However, when disabling the option in Visual Studio in 'Debug > Options > Enable Just My Code', antlr.MismatchedTokenException is thrown for almost every SQL query which is run through the parser.
Here's a simplified example, which throws:
antlr.MismatchedTokenException 'expecting "Dot", found 'AS''
Ignoring the exceptions, the select statement works fine and is passed to the app no problem. But the constant spam of .NET exceptions is puzzling. The literal interpretation of the exception doesn't seem to make sense for this SQL query.
I can't see anything wrong with this example query.
private static StatementList PrepareSql(string sql)
{
sql = "SELECT A.[ID] AS [Activities_Id] FROM [Activities] A";
var parser = new TSql140Parser(false, SqlEngineType.SqlAzure);
return parser.ParseStatementList(new StringReader(sql), out var errors1);
}
--
Update:
We believe the exception occurs not in the immediate library referenced by the portal, but in ANTLR. We still cannot find the reason for the exception. Currently we've added a workaround to cache the SQL query so that the exception is only thrown once per query - but that's still one too many.
In the software called Roblox studio I need help making a script that whenever an error happens in game, it would print out the error again using the normal print function something like this example here:
Local error = —-whatever the error that happened was
Print(error) —- so it just simply prints it back out
Roblox provides a few different ways to keep track of when errors are thrown in your Scripts and LocalScripts.
If you want to observe errors locally in a script, and you know a specific chunk of code may throw errors, you can use pcall() as a try-catch block.
local success, result = pcall(function()
error("this is a test error message")
end)
if not success then
print("An error was thrown!")
print(result) --"this is a test error message"
end
If you want to observe errors across all of your scripts, you can attach a callback to the ScriptContext.Error signal. This signal fires any time any error is thrown. It provides information about the error, including the message, the callstack, and a reference to the script that threw the error.
Warning : ScriptContext.Error only fires in the context of the script that registers it. A Script will only observe errors thrown in server scripts, and registering in a LocalScript will only observe errors thrown on the client.
local ScriptContext = game:GetService("ScriptContext")
ScriptContext.Error:Connect( function(message, stack, context)
print("An error was thrown!")
print("Message : ", message)
print("Stack : ", stack)
print("Context :", context:GetFullName())
end)
Similarly, if you only care about the error messages themselves, you can also observe them being printed out to the Output window using the LogService.MessageOut signal. This signal fires any time anything is logged to Output. This includes messages, warnings, and errors.
local LogService = game:GetService("LogService")
LogService.MessageOut:Connect( function(message, messageType)
if messageType == Enum.MessageType.MessageError then
print("An error was thrown!")
print(message)
end
end)
Use the stderr stream from io library to print debug messages.
-- Define debug function based in print
function debug(...) io.stderr:write(table.concat({...}, '\9') .. '\n') end
-- Debug acts as a regular "print()", but it writes to stderr instead
debug('[filename.lua]', 'debug')
Use "error()" function to print errors.
if true then
error("It should not be true!")
end
If you want to catch errors from a function, use xpcall()
-- Define debug
function debug(...) io.stderr:write(table.concat({...}, '\9') .. '\n') end
xpcall(
function()
local b = {}
-- This will throw an error because you cant index nil values
print(a.b)
end,
function(err)
debug('[xpcall]', err)
end
)
xpcall() wont stop the execution in case of error, so you only need to encapsulate your code in it if you want to catch any unexpected errors at runtime.
Folks,
Got an odd one for you.
I've got a stored procedure I use to parse some tabular data to create proper SQL geometry objects.
The SP makes use of the function MakeValid().
In my case I have found some objects that fail the test. These do not break the stored procedure however. The Stored procedure is happy to run and simply show the error in the results.
Msg 6522, Level 16, State 1, Line 257 A .NET Framework error occurred
during execution of user-defined routine or aggregate "geometry":
System.FormatException: 24306:
However when I execute this SP in a scheduled job, the first time it encounters one of these exceptions the job fails and the SP stops running.
I'm actually not sure what to do here. I've tried a TRY..CATCH block but this doesn't stop the error being raised and the job exits anyway.
So while it's a MakeValid function that's raising the error I would imagine an SP that encounters a function error would cause the same issue.
Any thoughts how I might handle this? BTW I have no control over the input quality other than to flag the errors and then go back and repair them. I'd still like the rest of the valid records to be processed though.
Here's the operable section of code.
SET #GEOM = geometry::STGeomFromText(#GEOMWKT, 4326)
IF #GEOM.STIsValid() = 0
BEGIN
BEGIN TRY
SET #GEOM = #GEOM.MakeValid()
END TRY
BEGIN CATCH
Print 'Error here'
END CATCH
END
Here is an example of an invalid geometry that throws an error.
SET #GEOM = geometry::STGeomFromText('LINESTRING(-121.895652 37.37225, -121.895652 37.37225)', 4326)
Thanks for any and all assistance.
I'm having a hard time validating that this will work for you (i.e. my local instance is too good at calling MakeValid()), but this might just work for you.
using Microsoft.SqlServer.Server;
using Microsoft.SqlServer.Types;
using System.Data.SqlTypes;
public partial class UserDefinedFunctions
{
[SqlFunction]
public static SqlGeometry TryMakeValid_geometry(SqlGeometry g)
{
SqlGeometry r;
try
{
r = g.MakeValid();
}
catch (System.Exception)
{
r = SqlGeometry.Null;
}
return r;
}
[SqlFunction]
public static SqlGeometry TryParseWKT_geometry(SqlString wkt)
{
SqlGeometry r;
try
{
r = SqlGeometry.Parse(wkt).MakeValid();
}
catch
{
r = SqlGeometry.Null;
}
return r;
}
}
Deploy this CLR to your database and call the function with your geometry instance. It should return NULL if the call to MakeValid() fails.
OK this is the answer that I'm going with but significant credit goes to Ben Thul for the CLR which achieves the same result using a different method.
The realisation is more correctly understanding the question. I made two mistakes. The first was not realising the error I was trying to catch was outside the TRY..CATCH block. The second was believing I needed to try and validate the WKB expression of the geometry. In fact, the following method allows the validation of the WKT before attempting to create a WKB. The following method identifies the invalid WKT, sets a TRUE/FALSE condition. With the WKT validated a valid WKB can be safely created.
Once I understood the question asking the right question turned up the solution here.
https://gis.stackexchange.com/questions/66642/detecting-invalid-wkt-in-text-column-in-sql-server
I have adapted the code to suit my implementation.
/*REVISED CODE*/
DECLARE #valid bit
DECLARE #GEOMWKT varchar(max)
DECLARE #GEOM geometry
Set #GEOMWKT = 'LINESTRING(-121.895652 37.37225, -121.895652 37.37225)'-- Test faulty value
Set #valid = 1
--Test WKT
BEGIN TRY --The is the test here.
SET #valid = geometry::STGeomFromText(#GEOMWKT, 4326).STIsValid()--We don't try to
END TRY --MakeValid(). No point.
BEGIN CATCH
SET #valid = 0
END CATCH
--Now that we know whether the WKT will pass or fail we can operate in a known
--state and avoid raising an error
IF #valid = 1
BEGIN
SET #GEOM = geometry::STGeomFromText(#GEOMWKT, 4326)--Safely create a valid WKB
END
ELSE
BEGIN
SET #GEOM = geometry::STGeomFromText('POINT EMPTY', 4326)-- Set geometry to empty on fail
Print 'Geometry Fail'
END
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.
Hello i've this function to update my Access DB using TUniQuery :
var
Res:Boolean;
begin
Res:=false;
try
with MyQuery do
begin
Active := false;
SQL.Clear;
SQL.Add('Update MYTABLE');
SQL.Add('set username='+QuotedStr(NewUserName));
SQL.Add(',password='+QuotedStr(NewPassword));
SQL.Add('where username='+QuotedStr(ACurrentUserName));
ExecSQL;
Res:=true;
end;
except
Res:=False;
end ;
Result:=Res;
end;
Is the use of Try ... except enough to KNOW when " ExecSQL " succeeds or fails ?
or is there any other better approach ?
thank you
You may want to consider your update succeeded if no exception is raised. It means the database is responsive and parsed and executed your statement without syntax errors.
In a statement like shown, you may also want to be sure that exactly one row was updated, because I assume that's your intention.
To check that, you can resort to the result of the ExecSQL method, which returns the number of rows affected by the execution of the statement. So, you may change your code to this:
begin
with MyQuery do
begin
Active := false;
SQL.Clear;
SQL.Add('Update MYTABLE');
SQL.Add('set username='+QuotedStr(NewUserName));
SQL.Add(',password='+QuotedStr(NewPassword));
SQL.Add('where username='+QuotedStr(ACurrentUserName));
Result := ExecSQL = 1; //exactly 1 row updated
end;
end;
I also changed the unconditional exception handler, since it may not be the proper site to eat any exception, and also removed the local variable to store the Result, since that really is not necessary.
After reading your added text and re-thinking your question:
Is the use of Try ... except enough to KNOW when " ExecSQL " succeeds or fails ?
You really have to change your mind about exception handling and returning a boolean from this routine. Exceptions were introduced as a whole new concept on how to address exceptional and error situations on your programs, but you're killing this whole new (and IMHO better) approach and resorting to the old way to return a value indicating success or failure.
Particularly a try/exception block that eats any exception is a bad practice, since you will be killing exceptions that may be raised for too many reasons: out of memory, network problems like connection lost to database, etc.
You have to re-think your approach and handle these exceptional or error conditions at the appropriate level on your application.
My advise is:
change this from a function to a procedure, the new contract is: it returns only if succeded, otherwise an exception is raised.
if an exception occurs let it fly out of the routine and handle that situation elsewhere
raise your own exception in case no exactly 1 row is updated
change the query to use parameters (avoiding sql injection)
The routine may look like this:
procedure TMySecurityManager.ChangeUserNameAndPassword();
begin
MyQuery.SQL.Text := 'Update MYTABLE'
+ ' set username = :NewUserName'
+ ' , password = :NewPassword'
+ ' where username = :username';
MyQuery.Params.ParamByName('NewUserName').AsString := NewUserName;
MyQuery.Params.ParamByName('NewPassword').AsString := NewPassword;
MyQuery.Params.ParamByName('username').AsString := ACurrentUserName;
if MyQuery.ExecSQL <> 1 then
raise EUpdateFailed.Create('A internal error occurred while updating the username and password');
//EUpdateFailed is a hypotetical exception class you defined.
end;