I want to check & parse sql script so I searched for that and I found something like this
SET PARSEONLY ON
SELECT * FROM [dbo].[Categories] --Query To Parse
I use dapper, so I write method like this
public bool IsValidSqlScript(string sqlScript)
{
using (SQLConnection)
{
using (SQLTransaction)
{
var status = SQLConnection.Execute("SET PARSEONLY ON " + sqlScript);
// OR
// var status = SQLConnection.Query("SET PARSEONLY ON " + sqlScript);
}
}
return status;
}
How I can get status and if exists any errors get error`s list also ???
SET PARSEONLY ON
SELECT * FR OM [dbo].[Categories] --Query To Parse
>>> false
>>> Msg 102, Level 15, State 1, Line 2 Incorrect syntax near 'FR'.
You're close, but you've got an issue with your status variable. You declare it inside your SQLTransaction using statement and then you try and return it outside of that scope.
You'll want to use a try/catch block to execute your query, that way you'll know when the sqlScript is valid or not. If you enter the catch block, it's invalid, and if you don't then it is valid.
The code should look similar to the following...
public bool IsValidSqlScript(string sqlScript)
{
bool status;
try
{
using (SQLConnection)
{
using (SQLTransaction)
{
SQLConnection.Execute("SET PARSEONLY ON " + sqlScript);
}
}
status = true;
}
catch(Exception e)
{
status = false;
)
return status;
}
Related
I have an SQL statement that checks to see if a value is in my database or not. I want to respond with the "happy path" if the value is not in the database.
I have found using DbDataReader (.NET) that if a SELECT query can't find the value it throws an exception - so my "happy path" ends up in the exception, not in the main try block.
I can always say "NOT IN" but I don't want to return all of the rows in the database that don't have the value - as this would return many thousands of results where as all I want is just a "no it is not here" type response.
public void wristbandScan(string barcode)
{
string query = "SELECT ticket FROM tickets WHERE
linked_barcode='" + barcode + "'";
ValidTicketEventArgs args = new ValidTicketEventArgs();
try
{
var queryResult = _dbRunner.queryThis(query);
args.Result = false;
args.Message = "WB already linked";
args.Barcode = barcode;
OnValidTicketEvent(args);
}
catch (Exception e)
{
this.updateWristband(barcode);
this.updateValid();
args.Result = true;
args.Message = "WB linked";
args.Barcode = barcode;
OnValidTicketEvent(args);
}
}
It feels wrong to me to catch the happy path in an error statement, but I do not want the lag associated with reading in all the rows with the NOT IN statement.
Is there a better way to do this or is this approach acceptable best practice?
Well, you don't have to fetch all the records to the client; let's extract a method for this. Assuming that you work with MS Sql:
public bool hasScanCode(string barcode) {
if (string.IsNullOrWhiteSpace(barcode))
return false;
//DONE: paramterize queries
string query =
#"SELECT ticket
FROM tickets
WHERE linked_barcode = #prm_BarCode";
using (var conn = new SqlConnection(connection_string_here)) {
conn.Open();
using (var q = new SqlCommand(conn, query)) {
//TODO: q.Parameters.Add is a better choice
q.Parameters.AddWithValue("#prm_BarCode", barcode.Trim());
using (var reader = q.ExecuteReader()) {
// we read (fetch) at most 1 record
// if empty cursor - no record with given barcode
return reader.Read();
}
}
}
}
then we can use it:
public void wristbandScan(string barcode) {
bool result = hasScanCode(barcode);
ValidTicketEventArgs args = new ValidTicketEventArgs() {
Result = result,
Message = result ? "WB linked" : "WB already linked",
Barcode = barcode,
};
OnValidTicketEvent(args);
}
Please, remember - exceptions are for exceptional situations. Exceptions are very slow (stack unrolling wants resources); they are not readable - catch, in fact, works as a notorious goto; they are dangerous - in your current code you catch too many exceptions: e.g. AccessViolationException if it's thrown somewhere within dbRunner.queryThis will be efficiently masked.
Create and call a StoredProcedure which can to handle the empty situation and return no rows instead of an exception.
Then handle the no rows scenario outside the try/catch.
I am going through a YouTube video, to learn ASP.NET. I've gotten it to work for the most part, with a somewhat major caveat: I can't retrieve a value from a hidden field ID. Because of that, I don't have a value to send to a stored procedure to create or update.
The commented out line is the original statement. When I have that then execute
.ExecuteNonQuery, I get the following error:
Procedure or function 'ResourceCreateOrUpdate' expects parameter '#ResourceID', which was not supplied
When I try to display hfResourceID, I have nothing when trying to pass 0, for a create, or the ResourceID value, i.e. 1. That value however, doesn't get there. I know the stored procedure works because I can execute it in SQL Server Management.
I tried moving hfResourceID to a string, then a integer value, but I seem to be having problems creating the if/else: everything is marked as an error. When I hover over the lines, I get the following message, which pretty much leave me clueless:
"Embedded statement cannot be a declaration or labeled statement".
Would I be able to get any pointers on how to clear up my error, please? Thanks.
2017-10-13 # 10:38: code updated
<asp:HiddenField ID="hfResourceID" runat="server" />
protected void btnSave_Click(object sender, EventArgs e)
{
int intResourceID = 0;
bool boolIDHasValue = true;
try
{
intResourceID = Convert.ToInt32(hfResourceID.Value);
}
catch (Exception ex)
{
lblErrorMessage.Text = ex.Message;
boolIDHasValue = false;
}
if (boolIDHasValue)
{
if (sqlconnODRConnection.State == System.Data.ConnectionState.Closed)
sqlconnODRConnection.Open();
SqlCommand sqlcmdCreateOrUpdate = new SqlCommand("ResourceCreateOrUpdate", sqlconnODRConnection);
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#ResourceID", intResourceID);
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#Status", txtStatus.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#FirstName", txtFirstName.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#MiddleName", txtMiddleName.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#LastName", txtLastName.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#NickName", txtNickName.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#Gender", txtGender.Text.Trim());
sqlcmdCreateOrUpdate.Parameters.AddWithValue("#USCitizen", txtUSCitizen.Text.Trim());
sqlcmdCreateOrUpdate.ExecuteNonQuery();
sqlconnODRConnection.Close();
string strResourceID = hfResourceID.Value;
Clear();
if (strResourceID == "")
lblSuccessMessage.Text = "Saved Successfully";
else
lblSuccessMessage.Text = "Updated Successfully";
FillGridView();
}
}
There are a few issues with the code you copied from that video. But here a snippet as to how it should be done. I've added 3 ways to convert from the HiddenField value to an actual int. Which one you use can depend on how you want to handle errors, 0 values etc. Not included in the snippet, but I like to check for IsNullOrEmpty while using Trim(), that gets rid of spaces that might make the value non-convertible if (!string.IsNullOrEmpty(hfResourceID.Value.Trim())).
int intResourceID = 0;
//this will try to convert but you won't see exeptions when failed
Int32.TryParse(hfResourceID.Value, out intResourceID);
//checks if there is a value in the hiddenfield, but throws yellow screen if not convertible
if (!string.IsNullOrEmpty(hfResourceID.Value))
{
intResourceID = Convert.ToInt32(hfResourceID.Value);
}
//catch an error when the value is not convertible, can be wrapped with !string.IsNullOrEmpty(hfResourceID.Value)
try
{
intResourceID = Convert.ToInt32(hfResourceID.Value);
}
catch (Exception ex)
{
//handle the error, can be seen with ex.Message
}
//if the hidden value is still 0 (for whatever reason) you might not want to execute the query
//so the next part will return and stop executing the rest of the code
if (intResourceID == 0)
{
return;
}
//update the database, using 'using' will ensure proper closure of the connection and disposing of any objects
using (SqlConnection connection = new SqlConnection("myConnectionString"))
using (SqlCommand command = new SqlCommand("ResourceCreateOrUpdate", connection))
{
//set the command type and add the parameters
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#ResourceID", SqlDbType.Int).Value = intResourceID;
try
{
//open the database connection and execute the command
connection.Open();
command.ExecuteNonQuery();
}
catch (Exception ex)
{
//there was an error opening the database connection or with the command, can be viewed with ex.Message
}
}
Your error regarding the embedded statement is because you a declaring
if (strResourceID == "")
int intResourceID = 0;
else
int intResourceID = (Convert.ToInt32(hfResourceID.Value));
When decalring a variable directly after an If or else then you need your curly brackets. So...
if (strResourceID == "")
{
int intResourceID = 0;
}
else
{
int intResourceID = (Convert.ToInt32(hfResourceID.Value));
}
As for your other issues I would need to see your client side code.
Take a look on ASP code, specifically the way you are setting hidden field value. I guess it is properly marked as runat=server but maybe some problem is going on in your asp.net code, try to debug client code by using: console.log function and see the output in your console browser.
I have an insertion query in this function :
public string Insert_Piece(List<Piece> liste)
{
this.Connect();
using (connexion)
{
using (SqlCommand sqlCmd = new SqlCommand("INSERT INTO Piece (IDPiece, IDSuperlot, Url) VALUES (#idpiece, #idsuperlot, #url)", connexion))
{
foreach (Piece p in liste)
{
sqlCmd.Parameters.AddWithValue("#idpiece", p.Id_piece);
sqlCmd.Parameters.AddWithValue("#idsuperlot", p.Id_super_lot);
sqlCmd.Parameters.AddWithValue("#url", p.Url_piece);
try
{
sqlCmd.ExecuteNonQuery();
}
catch (Exception e) { return e.ToString(); }
}
return "cava";
}
}
}
But always an exception appears:
I don't know what is the problem and how can i fix it . The 3 attributs are string (varchar) and the selection queries works fine without problem.
What is the matter?
How can i fix it?
It looks like the issue is you are trying to insert too long of a string into the varchar column, try making the varchar column larger or changing it to be a text column.
I have a quite simple UPDATE statement and it works correctly but for only one call. I have few projects (FAIs) in database and I want to change responsible person.
If I want to change two or more responsibles it only changes the responsible person for the last project. I don't have any error messages. All values are correctly send to update query but the query just does not send it to the database.
public void updateFaiUBazu(string orderNumber, FAI fai, int serialNumber)
{
konekcija.Open();
MessageBox.Show(fai.Reviewer);
komanda = new SqlCommand("
update FAI set
AircraftFK = #AircraftFK, GlassFK = #GlassFK, PartNumber = #PartNumber,
SerialNumber = #SerialNumber, ReportNumber = #ReportNumber,
Reviewer = #Reviewer, Comment = #Comment, DateTime = #DateTime,
Iges = #Iges, IgesName = #IgesName, Status = #Status
where
AircraftFK = " + fai.AircraftFK1 +
" and GlassFK = " + fai.GlassFK1 +
" and SerialNumber = " + serialNumber,
konekcija);
try
{
komanda.Parameters.Clear();
komanda.Parameters.AddWithValue("#AircraftFK", fai.AircraftFK1);
komanda.Parameters.AddWithValue("#GlassFK", fai.GlassFK1);
// komanda.Parameters.AddWithValue("#OrderNumberFK", fai[i].OrderNumerFK);
komanda.Parameters.AddWithValue("#PartNumber", fai.PartNumber);
komanda.Parameters.AddWithValue("#SerialNumber", fai.SerialNumber);
komanda.Parameters.AddWithValue("#ReportNumber", fai.ReportNumber);
komanda.Parameters.AddWithValue("#Reviewer", fai.Reviewer);
komanda.Parameters.AddWithValue("#Comment", fai.Comment);
komanda.Parameters.Add("#DateTime", fai.DateAndTime);
if (fai.IgesFile.Length != 0)
{
komanda.Parameters.AddWithValue("#Iges", fai.IgesFile);
}
else
{
komanda.Parameters.Add("#Iges", SqlDbType.VarBinary, -1);
komanda.Parameters["#Iges"].Value = DBNull.Value;
}
if (string.IsNullOrEmpty(fai.IgesName))
{
komanda.Parameters.Add("#IgesName", fai.IgesName).Value = DBNull.Value;
}
else
{
komanda.Parameters.AddWithValue("#IgesName", fai.IgesName);
}
komanda.Parameters.AddWithValue("#Status", "Not Tested");
komanda.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
konekcija.Close();
}
Could that be some limitation with SqlServer update statement?
Follow a couple of steps to get to your problem.
Log yout update queries. JUst after you have created it. This will tell you if your updates are really executed when you are calling them from a loop.
If all your updates are logged, copy them to SSMS query window and execute them one by one in sequence. This would give you corect idea if there is anything wong with way queries are getting formed, or of there is any specific value in one of the parameters which is causing the problem. This will also help you identify if the problem specified by #Steve above exists.
I am trying to implement prepared staments in my code as a way of adding parameters to sql commands that are retrieved from a table held in any generic server. I cannot seem to get it right. I get the following error:
ORA-00936: missing expression
ORA-00936: missing expression
Prepare Statement: select VALUE from RWOL_CONFIGURATION where ID = #ItemId
My guess is that it just isn't replacing the value but I dont know what I am missing.
I am trying the following to achieve the desired result. I create my object, get a query string out of our table in the database, add that to the command, add parameters to a list object and then use the final method shown below to tie it all together and run the query:
//This function gets me a config item from the database
private string GetConfigurationItem(string itemId)
{
//new database connection object
OleDataBaseConnection oleDataBaseConnection = new OleDataBaseConnection();
//todo get this query from the sql factory
SqlFactory sqlFactory = new SqlFactory();
//This method gets the query string from the database
string sqlQuery = sqlFactory.GetQueryString("GET_CONFIGURATION_ITEM", m_dialect);
if (!String.IsNullOrEmpty(sqlQuery))
{
//add parameter to list
oleDataBaseConnection.AddStoredProcedureParameter("#ItemId", itemId);
//execute the sql command after adding the parameters to the command
oleDataBaseConnection.OleExecutePrepareStatementWithParametersQuery(sqlQuery);
string returnValue = oleDataBaseConnection.NextRecord() ? oleDataBaseConnection.GetFieldById(0) : "Error";
oleDataBaseConnection.Close();
return returnValue;
}
else
{
return "ERROR";
}
}
//adds the parameters to list objects ready for the next method
public void AddParameter(string parameter, object value)
{
m_parameterName.Add(parameter);
m_parameterValue.Add(value);
} // End of void AddParameter()
/// <summary>
/// Executes a command with the parameters passed to AddParameter(parameterName, parameterValue) and creates a recordset.
/// </summary>
///
/// <param name="commandName">The name of the stored procedure to execute.</param>
public bool OleExecutePrepareStatementWithParametersQuery(string commandName)
{
if (String.IsNullOrEmpty(commandName))
{
return false;
}
try
{
PrepareConnection();
m_oleDatabaseCommand.CommandText = commandName;
m_oleDatabaseCommand.CommandType = CommandType.StoredProcedure;
if (m_storedProcedureParameterName.Count != 0)
{
for (int i = 0; i < m_storedProcedureParameterName.Count; i++)
{
m_oleDatabaseCommand.Parameters.AddWithValue(m_storedProcedureParameterName[i], m_storedProcedureParameterValue[i]);
}
m_storedProcedureParameterName.Clear();
m_storedProcedureParameterValue.Clear();
}
m_hasRecordSet = true;
m_oleDatabaseDataReader = m_oleDatabaseCommand.ExecuteReader();
return true;
}
catch (Exception ex)
{
if (QueueErrors)
{
QueuedErrorsList.AppendLine(ex.Message);
QueuedErrorsList.AppendLine("Prepare Statement: " + storedProcedureName);
QueuedErrorsList.AppendLine();
QueuedErrorCount++;
return false;
}
try
{
Close();
}
catch
{
}
throw new Exception(ex.Message + "\r\n\r\nPrepare Statement: " + storedProcedureName);
}
} // End of void OleExecutePrepareStatementWithParametersQuery()
Sorry if there is a lot of code but it is fairly straightforward and I thought it would help with the problem.
Is there anything obvious that would stop this from working?
The problem is that the OleDB provider does not support named parameters in the query.
This:
select VALUE from RWOL_CONFIGURATION where ID = #ItemId
Should be:
select VALUE from RWOL_CONFIGURATION where ID = ?
See OleDbParameter on MSDN for examples.