Java & SQL Server exception: The statement did not return a result set - sql-server

I'm creating an insurance management system for my DBMS project in university, and I am having a problem with deleting a record from SQL Server. It throws an exception:
SqlException: com.microsoft.sqlserver.jdbc.SQLServerException: The statement did not return a result set.
It also successfully deleted a record from my database. Could anyone please tell me how to remove this kind of exception?
String SQL="delete from INMS_3 where Agent_Id=? and First_Name=? and Last_Name=? and User_Name=? and Phone_no=?";
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String connectionUrl = "jdbc:sqlserver://localhost:1433;" +
"databaseName=INMS;user=TestingUser;password=1234;";
Connection con = DriverManager.getConnection(connectionUrl);
System.out.println("Connected to sql server");
String str=jTextField1.getText();
String str1=jTextField2.getText();
String str2=jTextField3.getText();
String str3=jTextField4.getText();
String str4=jTextField5.getText();
PreparedStatement st = con.prepareStatement(SQL);
st.setString(1, str);
st.setString(2,str1);
st.setString(3,str2);
st.setString(4,str3);
st.setString(5, str4);
ResultSet rs = st.executeQuery();
if(rs.next());
{
JOptionPane.showMessageDialog(null,"Deleted Succesfully");
}
if(!rs.next())
{
JOptionPane.showMessageDialog(null,"Unable to delete");
}
else
{
JOptionPane.showMessageDialog(null,"Unable to delete");
}
} catch (SQLException e) {
System.out.println("SQL Exception: "+ e.toString());
} catch (ClassNotFoundException cE) {
System.out.println("Class Not Found Exception: "+ cE.toString());
}

I think you are using the wrong thing to perform the delete operation.
Try using st.executeUpdate() instead of ResultSet rs = st.executeQuery() - you are executing a delete rather than something that would return a result set.

This is not a problem with SQL Server. The problem is with your code (what is that? C#? The object is set to expect a result set from the server, but the query is a DELETE statement, and those return no rows... ever.
State the programing language, and research for how to execute statement instead requesting result sets.
This line makes sense for a SELECT not for an UPDATE
ResultSet rs = st.executeQuery();

if you're executing a delete statement, why are you executing
ResultSet rs = st.executeQuery();
Here's a sample c# ado.net. concept it the same if you're using java.
using(var conn = new SqlConnection("my connection string"))
{
var deleteCmd = new SqlCommand();
deleteCmd.Connection = conn;
deleteCmd.CommandType = CommandType.Text;
deleteCmd.CommandText = #"
DELETE Accounts
WHERE account_id = #p_account_id
";
deleteCmd.Parameters.AddWithValue("p_account_id", 123);
conn.Open();
deleteCmd.ExecuteNonQuery();
}

Related

Second Order SQL Injection - PreparedStatement

The following section of my code is raising concern in "Second-Order SQL Injection".
private String function1 (String var1) {
String sql = "SELECT field1 FROM table1 WHERE field2 = ?";
PreparedStatement ps = null;
ResultSet resultSet = null;
String result = "";
try{
ps = conn.prepareStatement(sql);
ps.setString(1, var1);
resultSet = ps.executeQuery();
if(resultSet.next()){
result = rs.getString("fldDesc");
}
}catch(SQLException e){
e.printStackTrace();
}
}
However, as I know the preparedStatement should be safe against the 2nd Order SQL Injection, due to the separation of query and data.
Can I know why does it would raise a concern against it?

ADO.NET - Trouble Getting Output Parameter

My DBA created the following Stored Proc which he insists works fine when called in SQL Server:
CREATE procedure [dbo].[GetParentID]
#SSHIP_AppID as varchar(50),
#ParentID as varchar(150) OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT #ParentID = a.iBuild_GUID
FROM dbo.XRef_iBuild_SSHIP as a
WHERE a.SSHIP_appId = #SSHIP_AppID
AND a.SSHIP_appId <> ''
END
I have created the following ADO.NET Wrapper but I am having trouble getting the output parameter. I keep getting back "OUTPUT" as its value:
private string GetParentId(string appId)
{
var connection = new SqlConnection();
string parentId = String.Empty;
try
{
connection.ConnectionString = "...)
var command = new SqlCommand("GetParentId", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#SSHIP_AppID", appId));
command.Parameters.Add(new SqlParameter("#ParentID", ParameterDirection.Output));
connection.Open();
command.ExecuteNonQuery();
parentId = (command.Parameters["#ParentId"].Value).ToString();
}
catch (Exception ex)
{
LogError(appId, ex.ToString(), "Interface12 - Cannot get ParentId", null, 0);
}
finally
{
connection.Close();
}
return parentId;
}
}
What am I doing wrong?
In new SqlParameter("#ParentID", ParameterDirection.Output) the 2nd argument is treated as the object value argument and apparently converted to a string.
(This implicit conversion is, in my opinion, a design flaw in ADO.NET. It should throw an exception for any unknown input type.).
Choose a better overload.

Maximum length of string which can be returned from stored proc in SQL Server 2008 to .net apps

I am returning a static string from a stored procedure (in SQL Server 2008) as below:
select 'abcdefgh.........xyz'
If the static string length is exceeding more than some limit (eg:8kb) then only partial string (eg:7kb) is returned to the .net apps.
Though I tried in different ways like assigning static string to varchar(max) and selecting the variable, is still returning only partial string.
I should return complete string which could be of max of 5mb. So, main concerns:
What is the max string length I can return from a stored procedure
How to return 5 mb string from stored procedure to .net apps.
I request someone can help me to resolve this issue.
please find the code below
using (SqlCommand command = new SqlCommand(Source.GetExportRecordSP, Connection))
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#CandidateRecordID ", SqlDbType.NVarChar, 32)).Value = record;
try
{
if (Connection.State != ConnectionState.Open)
{
Connection.Open();
}
using (SqlDataReader reader = command.ExecuteReader())
{
if(reader.Read())
{
xmlRecord = new XmlDocument();
xmlRecord.LoadXml(reader.GetString(0));
}
}
}
catch (Exception Ex)
{
Logging.WriteError(string.Format("Error while retrieving the Record \"{0}\" details from Database. Exception: {1} ", Ex.ToString()));
throw;
}
}
Thanks in advance geeks.
Since you appear not to be using an OLEDB connection (which has an 8k limit), I think the problem is in your procedure code.
Or, perhaps, the compatibility version of your database is set to something other than SQL Server 2008 (SQL Server 2000 could not return more than 8k using GetString()).
Thanks for support, I found 1 fix for this at
http://www.sqlservercentral.com/Forums/Topic350590-145-1.aspx
Fix is, declare a variable, and should be initlized to empty string and concatenated with the main string.
DECLARE #test varchar(MAX);
set #test =''
select #test = #test + '<Invoice>.....'
If the string length is <8000 it will work without the above approach.
Thanks all.

How to know whether a sql Update statement executed successfully or failed?

How to know whether a sql Update statement executed successfully or failed ?
I use sql server 2005 and C# asp.net.
Can I get the successful or failed infomation in C# without adding some sql code into the old sql statement?
You can use ##ROWCOUNT to get the number of rows affected by the last query. This can be used to decide whether your WHERE clause actually matched something, for example.
UPDATE mytable SET
field = 'SomeValue'
WHERE
id = 1234
IF ##ROWCOUNT = 0
BEGIN
-- No row with id=1234
END
You can use the return value of the ExecuteNonQuery to check if the update was successful or not.
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
SqlCommand cmd = new SqlCommand("sp_updateData", con);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter p1 = new SqlParameter("#id", SqlDbType.Int);
p1.Value = 1;
p1.Direction = ParameterDirection.Input;
SqlParameter p2 = new SqlParameter("#name", SqlDbType.VarChar,50);
p2.Value = "sls";
p2.Direction = ParameterDirection.Input;
cmd.Parameters.Add(p1);
cmd.Parameters.Add(p2);
try
{
con.Open();
//count will be the number of rows updated. will be zero if no rows updated.
int count = cmd.ExecuteNonQuery();
if (count > 0)
{
Console.WriteLine("Update Success!!!");
}
else
{
Console.WriteLine("No Updates!!!");
}
Console.ReadLine();
}
catch (SqlException ex)
{
Console.WriteLine("Update Failed coz.. " + ex.Message);
}
finally
{
con.Close();
}
What does 'failed' mean?
If by failed you mean an error was generated - SQL Syntax, constraint- or FK-violation - then TRY/CATCH, RAISEERROR, etc. are options.
Or, if by failed you mean no rows were updated, then the return value of ExecuteNonQuery will give you a rowcount IF you're not suppressing rowcount in your stored procedure.
Using a TRY/CATCH block and maybe RAISERROR to send a message.
http://msdn.microsoft.com/en-us/library/ms179296.aspx
http://msdn.microsoft.com/en-us/library/ms178592.aspx

JDBC - prepareStatement - How should I use it?

I saw this example somewhere:
rs = connection.prepareStatement("select * from table").executeQuery();
Could I use this format, if I want to execute a query like this "Select * from table where column = "hello" "?
The way in which I usual I use prepareStatement object is something like this:
String sql = "select * from adresa where column = ?";
PreparedStatement pre = con.prepareStatement(sql);
pre.setString(1, i);
rs = pre.executeQuery();
Later Edit:
I don't understand. Pascal Thivent wrote that I can use the short version with In parameters, but Liu tells me this is not possible. :) Anw, using Pascal's version, i receive this error: void cannot be dereferenced
Here's a partial example how to use this interface:
static final String USER = "root";
static final String PASS = "newpass";
Connection conn = DriverManager.getConnection(myUrl, USER, PASS);
// create a sql date object so we can use it in our INSERT statement
Calendar calendar = Calendar.getInstance();
java.sql.Date startDate = new java.sql.Date(calendar.getTime().getTime());
// the mysql insert statement
String query = " insert into students (ID, last_name, first_name, birthday, hometown)"
+ " values (?, ?, ?, ?, ?)";
// create the mysql insert preparedstatement
PreparedStatement preparedStmt = conn.prepareStatement(query);
preparedStmt.setInt(1, 808027);
preparedStmt.setString(2, "Davis");
preparedStmt.setString(3, "Felicita");
preparedStmt.setDate(4, startDate);
preparedStmt.setString(5, "Venice");
// execute the preparedstatement
preparedStmt.execute();
conn.close();
You can only use the first form if there are no bind variables (question marks) in the query. It's just a shortened version of what you posted.
Also, if you use the shortened form you won't have the opportunity to reuse the PreparedStatement object.
of course u can use a string variable for the query in which u put in ur dynamic data and run it.
rs = connection.prepareStatement(variable).executeQuery();
The long form is often, but prepared statements can be precompiled by the db, and if used properly will help prevent sql injection.
Connection conn = null;
ResultSet rs = null;
PreparedStatement ps = null;
try {
conn = getConn();
ps = conn.prepareStatement("select * from x where y = ? "); //note no sb.append()'s or +'s, to helps prevent sql injection
ps.setLong(1, 12l);
rs = ps.executeQuery();
while (rs.next()) {
... act ...
}
} catch ( Exception e) {
} finally {
if (rs != null) rs.close();
if (ps != null) ps.close();
if (conn != null) conn.close();
}
Who said java was verbose. :)

Resources