How to throw a error or raise exception in U-SQL? - azure-data-lake

What is the mechanism used to raise an error or exception in a U-Sql script? I have a scenario where am processing a CSV file, and if duplicates are found in it, then I need to abandon processing.
In SQL, I could do raiseerror, what it the equivalent way of doing it in U-Sql?

Create a c# function to raise custom errors (or output to a file):
DECLARE #RaiseError Func<string, int> = (error) =>
{
throw new Exception(error);
return 0;
};
#Query =
SELECT #RaiseError(value) AS ErrorCode
FROM (VALUES ("my custom error description")) AS T(value);
OUTPUT #Query TO "/Output/errors.txt" USING Outputters.Csv(quoting : true);

Related

Is it possible to replace the whole JSON in a column with a new JSON

I have a code which executes a script where I want to update a column in a table with a completely new JSON data. I know it can be also done using Json_Modify but I want to know if it is possible to replace the old JSON data with new.
Code which executes the script as a raw SQL query:
public async Task Run(Args args)
{
var scrPath = Path.Combine(Directory.GetCurrentDirectory(), "FolderName", args.subFolderName);
var dataChangeSqlPath = Path.Combine(scrPath, args.DataChangeSqlFileName);
var query = await this.GetSql(dataChangeSqlPath);
await this.db.Database.ExecuteSqlRawAsync(query);
}
private async Task<string> GetSql(string path)
{
var sql = await File.ReadAllTextAsync(path);
return sql.ToString();
}
And this is the script it is trying to execute:
And this is the script it is trying to execute:
DECLARE #answers_json NVARCHAR(max);
BEGIN TRY
BEGIN TRANSACTION
SELECT
#answers_json = N'{"CONST_TRUE":{"type":"specified","boolValue":true}}'
BEGIN
UPDATE [dbo].[ColumnName]
SET
AnswersJson= #answers_json
WHERE
Id=2 AND Number=1;
END
COMMIT
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0 ROLLBACK TRANSACTION
SELECT
#error_message = ERROR_MESSAGE(),
#error_severity = ERROR_SEVERITY(),
#error_state = ERROR_STATE();
RAISERROR (#error_message, #error_severity, #error_state);
END CATCH
It throws and error:
System.FormatException: Input string was not in a correct format.
But when I execute the script directly in SQL Server then it works fine.
Any help/suggestion is much appreciated.
Thank you Charlieface and Prem Raj. Posting your discussions as answer to help other community members.
Use correct parameterization which ExecuteRawSql supports. For example ExecuteRawSqlAsync("INSERT YourTable (col) VALUES ({0})", yourJsonVariable)

PHP7 produce error when array push is used on a string

How can I configure PHP 7 to produce an error when an item is pushed to a string, for example:
$items = '';
$items[] = 'test';
Is this possible?
In PHP 5.6 and 7.0, it is valid to convert a variable containing an empty string into an array like this. Therefore, you will need to provide your own validation to produce an exception.
function checkAndAssign($var, $val){
if (is_string($var)){
throw new ErrorException('Do not assign array item to a string');
}
return $val;
}
$items = '';
try{
$items[] = checkAndAssign($items, 'test');
}catch(Exception $e){
echo $e->getMessage();
return;
}
var_dump($items);
Results in:
Do not assign array item to a string
In PHP 7.1 this generates a Fatal Error. There is already a good answer to the question How do I catch a PHP Fatal Error if you want to attempt that.

Dapper.Net and the DataReader

I have a very strange error with dapper:
there is already an open DataReader associated with this Command
which must be closed first
But I don't use DataReader! I just call select query on my server application and take first result:
//How I run query:
public static T SelectVersion(IDbTransaction transaction = null)
{
return DbHelper.DataBase.Connection.Query<T>("SELECT * FROM [VersionLog] WHERE [Version] = (SELECT MAX([Version]) FROM [VersionLog])", null, transaction, commandTimeout: DbHelper.CommandTimeout).FirstOrDefault();
}
//And how I call this method:
public Response Upload(CommitRequest message) //It is calling on server from client
{
//Prepearing data from CommitRequest
using (var tr = DbHelper.DataBase.Connection.BeginTransaction(IsolationLevel.Serializable))
{
int v = SelectQueries<VersionLog>.SelectVersion(tr) != null ? SelectQueries<VersionLog>.SelectVersion(tr).Version : 0; //Call my query here
int newVersion = v + 1; //update version
//Saving changes from CommitRequest to db
//Updated version saving to base too, maybe it is problem?
return new Response
{
Message = String.Empty,
ServerBaseVersion = versionLog.Version,
};
}
}
}
And most sadly that this exception appearing in random time, I think what problem in concurrent access to server from two clients.
Please help.
This some times happens if the model and database schema are not matching and an exception is being raised inside Dapper.
If you really want to get into this, best way is to include dapper source in your project and debug.

ORA-00604: error occurred at recursive SQL level 1

I started getting the below SQL exception and I don't know what's the root cause for this exception? I am also closing dbconnection and prepared statement too. Then what's the problem?
java.sql.SQLException: ORA-00604: error occurred at recursive SQL level 1
ORA-01000: maximum open cursors exceeded
ORA-00604: error occurred at recursive SQL level 1
ORA-01000: maximum open cursors exceeded
ORA-01000: maximum open cursors exceeded
Below is my code which I am using. Anything wrong in my code?
for (Entry<Integer, LinkedHashMap<Integer, String>> entry : GUID_ID_MAPPING.entrySet()) {
pstatement = db_connection.prepareStatement(PDSLnPConstants.UPSERT_SQL); // create a statement
pstatement.setInt(1, entry.getKey());
pstatement.setString(2, entry.getValue().get(PDSLnPConstants.CGUID_ID));
pstatement.setString(3, entry.getValue().get(PDSLnPConstants.PGUID_ID));
pstatement.setString(4, entry.getValue().get(PDSLnPConstants.SGUID_ID));
pstatement.setString(5, entry.getValue().get(PDSLnPConstants.UID_ID));
pstatement.setString(6, entry.getValue().get(PDSLnPConstants.ULOC_ID));
pstatement.setString(7, entry.getValue().get(PDSLnPConstants.SLOC_ID));
pstatement.setString(8, entry.getValue().get(PDSLnPConstants.PLOC_ID));
pstatement.setString(9, entry.getValue().get(PDSLnPConstants.ALOC_ID));
pstatement.setString(10, entry.getValue().get(PDSLnPConstants.SITE_ID));
pstatement.executeUpdate();
}
} catch (SQLException e) {
getLogger().log(LogLevel.ERROR, e);
} finally {
if (pstatement!= null) {
try {
pstatement.close();
pstatement = null;
} catch (SQLException e) {
getLogger().log(LogLevel.ERROR, e.getMessage(), e.fillInStackTrace());
}
}
if (db_connection!= null) {
try {
db_connection.close();
db_connection = null;
} catch (SQLException e) {
getLogger().log(LogLevel.ERROR, e.getMessage(), e.fillInStackTrace());
}
}
I think the PreparedStatement definition should be pulled out of the loop and reused within the loop by calling clearParameters:
pstatement = db_connection.prepareStatement(PDSLnPConstants.UPSERT_SQL); // create a statement
for (Entry<Integer, LinkedHashMap<Integer, String>> entry : GUID_ID_MAPPING.entrySet()) {
pstatement.setInt(1, entry.getKey());
pstatement.setString(2, entry.getValue().get(PDSLnPConstants.CGUID_ID));
pstatement.setString(3, entry.getValue().get(PDSLnPConstants.PGUID_ID));
pstatement.setString(4, entry.getValue().get(PDSLnPConstants.SGUID_ID));
pstatement.setString(5, entry.getValue().get(PDSLnPConstants.UID_ID));
pstatement.setString(6, entry.getValue().get(PDSLnPConstants.ULOC_ID));
pstatement.setString(7, entry.getValue().get(PDSLnPConstants.SLOC_ID));
pstatement.setString(8, entry.getValue().get(PDSLnPConstants.PLOC_ID));
pstatement.setString(9, entry.getValue().get(PDSLnPConstants.ALOC_ID));
pstatement.setString(10, entry.getValue().get(PDSLnPConstants.SITE_ID));
pstatement.executeUpdate();
pstatement.clearParameters();
}
You may also want to investigate batch processing (addBatch). If you are testing, you may need to wait a bit for the existing "open" cursors to be cleaned up.
Well I guess I am giving you one way I went around it but anyway a lot of people are going to come across such a problem so I might as well share.
I was using NetBeans 7.3.1 and referring to an Oracle Database on a remote Server so I couldn't edit the Registry Keys and instead I realised I was using ojdbc14.jar and all i needed was ojdbc6.jar in my classpath.
Solution: Used ojdbc6.jar instead of ojdbc14.jar

Problems executing SQL-script using Firebird.NET 2.5 (Error Code = -104)

Sorry for my English first of all. I have a problem and need help.
I have a simple tool made by myself on c#. This tool makes connect to local or remote firebird server (v.2.5). And my tool can create specified .fdb file (database) somewhere on the server.
Also I have a file with SQL statements (create table, triggers and so on). I want to execute this file after database was created. Executing this file will fill structure of user database - not data, only structure.
But then I try to execute my SQL script - firebird server returns a
SQL error code = -104 Token unknown line xxx column xxx.
That's the line on this CREATE TABLE SQL statement, for example:
CREATE TABLE tb1
(
col1 INTEGER NOT NULL,
col2 VARCHAR(36)
);
/* This next create statement causes an error */
CREATE TABLE tb2
(
col1 INTEGER NOT NULL,
col2 VARCHAR(36)
);
If I will leave only one create statement in my file - all will be good... I don't know how I explained (it's clear or not)) - another words - why can't I execute full query with many create statements in one transaction? There is my main method which executes query:
public static string Do(string conString, string query)
{
using (FbConnection conn = new FbConnection())
{
try
{
conn.ConnectionString = conString;
conn.Open();
FbTransaction trans = conn.BeginTransaction();
FbCommand cmd = new FbCommand(query, conn, trans);
cmd.ExecuteNonQuery();
trans.Commit();
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.ToString());
return "Transaction Fail";
}
}
return "Transaction Commited";
}
There is a query is my SQL file.
As Victor already stated in his final comment, you can use the FBScript class for batch execution.
I was just confronted with the same task. This question pointed me in the right direction but i had to do some further digging.
I this example, the source of the statements is a external script file:
private void ExecuteScript(FbConnection myConnection, string scriptPath) {
if (!File.Exists(scriptPath))
throw new FileNotFoundException("Script not found", scriptPath);
FileInfo file = new FileInfo(scriptPath);
string script = file.OpenText().ReadToEnd();
// use FbScript to parse all statements
FbScript fbs = new FbScript(script);
fbs.Parse();
// execute all statements
FbBatchExecution fbe = new FbBatchExecution(myConnection, fbs);
fbe.Execute(true);
}
This will work fine, but you may wonder why this whole thing isn't surrounded by a transaction. Actually there is no support to "bind" FbBatchExecution to a transaction directly.
The first thing i tried was this (will not work)
private void ExecuteScript(FbConnection myConnection, string scriptPath) {
using (FbTransaction myTransaction = myConnection.BeginTransaction()) {
if (!File.Exists(scriptPath))
throw new FileNotFoundException("Script not found", scriptPath);
FileInfo file = new FileInfo(scriptPath);
string script = file.OpenText().ReadToEnd();
// use FbScript to parse all statements
FbScript fbs = new FbScript(script);
fbs.Parse();
// execute all statements
FbBatchExecution fbe = new FbBatchExecution(myConnection, fbs);
fbe.Execute(true);
myTransaction.Commit();
}
}
This will result in an exception stating: "Execute requires the Command object to have a Transaction object when the Connection object assigned to the command is in a pending local transaction. The Transaction property of the Command has not been initialized."
This means nothing more than that the commands that are executed by FbBatchExecution are not assigned to our local transaction that is surrounding the code block. What helps here is that that FbBatchExecution provides
the event CommandExecuting where we can intercept every command and assign our local transaction like this:
private void ExecuteScript(FbConnection myConnection, string scriptPath) {
using (FbTransaction myTransaction = myConnection.BeginTransaction()) {
if (!File.Exists(scriptPath))
throw new FileNotFoundException("Script not found", scriptPath);
FileInfo file = new FileInfo(scriptPath);
string script = file.OpenText().ReadToEnd();
// use FbScript to parse all statements
FbScript fbs = new FbScript(script);
fbs.Parse();
// execute all statements
FbBatchExecution fbe = new FbBatchExecution(myConnection, fbs);
fbe.CommandExecuting += delegate(object sender, CommandExecutingEventArgs args) {
args.SqlCommand.Transaction = myTransaction;
};
fbe.Execute(true);
// myTransaction.Commit();
}
}
Note that i have uncommented the myTransaction.Commit() line. I was a little bit surprised by this behavior, but if you keep that line the transaction will throw an exception stating that it has already been committed. The bool parameter fbe.Execute(true) is named "autoCommit", but changing this to false seems to have no effect.
I would like some feedback if you see any potential issues with assigning the local transaction this way, or if it has any benefits at all or could as well be omitted.
Probably error in launching two create statements in one batch. Would it work if you break it to separate queries? Does it work in your SQL tool?