why is my resultset containing only one result when it was supposed to get two results - prepared-statement

I executed the same query in my db interface directly and got two rows as result... I thought i should be getting same here too... but it is returning only one and for the second it says column index out of range 2>1 !!!
session= request.getSession();
String name=(String)session.getAttribute("user");
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mutualfund", "root", "");
Statement statement = connection.createStatement();
String qry="SELECT `account_type_id` FROM `cust_accounts` WHERE `cust_id`=\""+name+"\"";
ResultSet rs = statement.executeQuery(qry) ;
if(!rs.next())
{
out.println("Server Down.. Please try again later ");
}
else {
String one=rs.getString(1);
String two=rs.getString(2);
}

Your code isn't asking for two rows, it's asking for two columns, and your query only supplies one.
if (!rs.next()) {
out.println("nope");
} else {
String one = rs.getString(1);
String two = "";
if (rs.next())
two = rs.getString(1);
}
}

Related

Syntax error in FROM clause Access

I want to read the data from Access Database in order to check if a password is correct or not. I use this code:
var check=false;
OleDbCommand c = new OleDbCommand();
c.Connection = co //the connection to the Database;
c.CommandText = "select * FROM User Where user_name='"+usee+"'";
OleDbDataReader re = c.ExecuteReader();
while (re.Read())
{
if (re.ToString() == pasy)
{
check = true;
}
}
It gives me a "Syntax error in FROM clause." when the code executes.
"User" is a reserved word for Access.
Here is a list of reserved words :
http://support.microsoft.com/kb/286335/en-us
and here is a page describing that problem :
http://support.microsoft.com/kb/181489/en-us

Objectify return List & Cursor

I am trying to use a cursor with Objectify and Google App Engine to return a subset of data and a cursor so that I can retrieve more data when the user is ready. I found an example here that looks exactly like what I need but I don't know how to return the final list plus the cursor. Here is the code I have:
#ApiMethod(name = "listIconThemeCursor") //https://code.google.com/p/objectify-appengine/wiki/Queries#Cursors
public CollectionResponse<IconTheme> listIconThemeCursor(#Named("cursor") String cursorStr) {
Query<IconTheme> query = ofy().load().type(IconTheme.class).limit(10);
if (cursorStr != null ) {
query.startAt(Cursor.fromWebSafeString(cursorStr));
}
List<IconTheme> result = new ArrayList<IconTheme>();
int count = 0;
QueryResultIterator<IconTheme> iterator = query.iterator();
while (iterator.hasNext()) {
IconTheme theme = iterator.next();
result.add(theme);
count++;
}
Cursor cursor = iterator.getCursor();
String encodeCursor = cursor.toWebSafeString();
return serial(tClass, result, encodeCursor);
}
Note that this was modified from a previous endpoint in which I returned the CollectionResponse of ALL the data. My dataset is large enough that this is no longer practical. Basically, I don't know what was in the user's function of 'serial(tClass, result, encodeCursor) that let it get returned to the user.
There is another example here but it doesn't appear to answer my question either.
I don't quite understand what you are asking, but I see one immediate bug in your code:
query.startAt(Cursor.fromWebSafeString(cursorStr));
...should be:
query = query.startAt(Cursor.fromWebSafeString(cursorStr));
Objectify command objects are immutable, functional objects.
After a long slog, I figured out that CollectionResponse has the cursor in it :(
Here is the complete code I used incorporating the comment from stickfigure above:
#ApiMethod(name = "listIconThemeCursor", path="get_cursor")
public CollectionResponse<IconTheme> listIconThemeCursor(#Named("cursor") String cursorStr) {
Query<IconTheme> query = ofy().load().type(IconTheme.class)
.filter("errors <", 10)
.limit(10);
if (cursorStr != null ) {
query = query.startAt(Cursor.fromWebSafeString(cursorStr));
}
List<IconTheme> result = new ArrayList<IconTheme>();
QueryResultIterator<IconTheme> iterator = query.iterator();
while (iterator.hasNext()) {
IconTheme theme = iterator.next();
result.add(theme);
}
Cursor cursor = iterator.getCursor();
CollectionResponse<IconTheme> response = CollectionResponse.<IconTheme> builder()
.setItems(result)
.setNextPageToken(cursor.toWebSafeString())
.build();
return response;
}

Using LINQ to find Excel columns that don't exist in array?

I have a solution that works for what I want, but I'm hoping to get some slick LINQ types to help me improve what I have, and learn something new in the process.
The code below is used verify that certain column names exist on a spreadsheet. I was torn between using column index values or column names to find them. They both have good and bad points, but decided to go with column names. They'll always exist, and sometimes in different order, though I'm working on this.
Details:
GetData() method returns a DataTable from the Excel spreadsheet. I cycle through all the required field names from my array, looking to see if it matches with something in the column collection on the spreadsheet. If not, then I append the missing column name to an output parameter from the method. I need both the boolean value and the missing fields variable, and I wasn't sure of a better way than using the output parameter. I then remove the last comma from the appended string for the display on the UI. If the StringBuilder object isn't null (I could have used the missingFieldCounter too) then I know there's at least one missing field, bool will be false. Otherwise, I just return output param as empty, and method as true.
So, Is there a more slick, all-in-one way to check if fields are missing, and somehow report on them?
private bool ValidateFile(out string errorFields)
{
data = GetData();
List<string> requiredNames = new [] { "Site AB#", "Site#", "Site Name", "Address", "City", "St", "Zip" }.ToList();
StringBuilder missingFields = null;
var missingFieldCounter = 0;
foreach (var name in requiredNames)
{
var foundColumn = from DataColumn c in data.Columns
where c.ColumnName == name
select c;
if (!foundColumn.Any())
{
if (missingFields == null)
missingFields = new StringBuilder();
missingFieldCounter++;
missingFields.Append(name + ",");
}
}
if (missingFields != null)
{
errorFields = missingFields.ToString().Substring(0, (missingFields.ToString().Length - 1));
return false;
}
errorFields = string.Empty;
return true;
}
Here is the linq solution that makes the same.
I call the ToArray() function to activate the linq statement
(from col in requiredNames.Except(
from dataCol in data
select dataCol.ColumnName
)
select missingFields.Append(col + ", ")
).ToArray();
errorFields = missingFields.ToString();
Console.WriteLine(errorFields);

From .NET can I get the full SQL string generated by a SqlCommand object (with SQL Parameters)?

From the .NET environment can I get access to the full SQL string that is generated by a SqlCommand object?
Note: The full SQL string shows up in Intellisense hover, in VisualStudio, while in debug mode.
I'm willing to use reflection techniques if I must. I'm sure somebody here knows a way to get at it.
Update 1:
I'm calling a stored procedure having parameters with cmd.CommandType = CommandType.StoredProcedure and am trying to acquire the full SQL generated and run.
I wonder if the cmd.Prepare() method might not prove useful in this circumstance, if it might store the full string in a state field or something like that.
Update 2:
In light of answers below (and referenced) that indicate no complete SQL string is generated internally during preparation or execution, I did a bit of poking around using .NET Reflector. Even the internal connection classes seem to pass objects rather than boiling them down to strings, for example:
internal abstract void AddPreparedCommand(SqlCommand cmd);
Declaring Type: System.Data.SqlClient.SqlInternalConnection
Assembly: System.Data, Version=2.0.0.0
In general, thanks to everybody for the level of detail you got into to prove what can be done and show what's actually happening. Much appreciated. I like thorough explanations; they add surety and lend credence to the answers.
A simple loop replacing all the parameter names with their values will provide you with something similar to what the end result is, but there are several problems.
Since the SQL is never actually rebuilt using the parameter values, things like newlines and quotes don't need to be considered
Parameter names in comments are never actually processed for their value, but left as-is
With those in place, and taking into account parameter names that starts with the same characters, like #NAME and #NAME_FULL, we can replace all the parameter names with the value that would be in the place of that parameter:
string query = cmd.CommandText;
foreach (SqlParameter p in cmd.Parameters.OrderByDescending(p => p.ParameterName.Length))
{
query = query.Replace(p.ParameterName, p.Value.ToString());
}
there is one problem left with this, however, and that is if a parameter is a string, then the SQL that initially looks like this:
SELECT * FROM yourtable WHERE table_code = #CODE
will look like this:
SELECT * FROM yourtable WHERE table_code = SOME CODE WITH SPACES
This is clearly not legal SQL, so we need to account for some parameter-types as well:
DbType[] quotedParameterTypes = new DbType[] {
DbType.AnsiString, DbType.Date,
DbType.DateTime, DbType.Guid, DbType.String,
DbType.AnsiStringFixedLength, DbType.StringFixedLength
};
string query = cmd.CommandText;
var arrParams = new SqlParameter[cmd.Parameters.Count];
cmd.Parameters.CopyTo(arrParams, 0);
foreach (SqlParameter p in arrParams.OrderByDescending(p => p.ParameterName.Length))
{
string value = p.Value.ToString();
if (quotedParameterTypes.Contains(p.DbType))
value = "'" + value + "'";
query = query.Replace(p.ParameterName, value);
}
There have been a couple of similar questions here.
The most compelling answer was provided to this question: How to get the generated SQL-Statment from a SqlCommand-Object?
and the answer was:
You can't, because it does not
generate any SQL.
The parameterized query (the one in
CommandText) is sent to the SQL Server
as the equivalent of a prepared
statement. When you execute the
command, the parameters and the query
text are treated separately. At no
point in time a complete SQL string is
generated.
You can use SQL Profiler to take a
look behind the scenes.
The CommandText property (or calling ToString()) on your command will give you all of the SQL, with a small exception. It will definitely give you anything you see in the debugger. Note that this won't give you parameter values, but it will give you the actual command.
The only caveat is that when CommandType is Text, the ADO.NET framework will often (in fact, almost always) use sp_executesql to execute the command rather than executing the command directly against the connection. In that sense, it's not possible to obtain the exact SQL that gets executed.
I haven't tried this, but you may be able to use Capture Mode if you are willing to use SMO:
http://msdn.microsoft.com/en-us/library/ms162182(v=sql.120).aspx
I like Jesus Ramos answer, but I needed support for output parameters. (I also used a string builder to generate the content.)
Declare Parameter for output parameters
foreach (SqlParameter p in arrParams.Where(x => x.Direction == ParameterDirection.Output || x.Direction == ParameterDirection.InputOutput))
{
// todo : I only needed a couple of types supported, you could add addition types
string dbtype = string.Empty;
switch (p.DbType)
{
case DbType.Guid:
dbtype = "uniqueidentifier";
break;
case DbType.Int16:
case DbType.Int64:
case DbType.Int32:
dbtype = "int";
break;
case DbType.String:
dbtype = "varchar(max)";
break;
}
query.Append(string.Format(" Declare {0}_ {1}\n", p.ParameterName, dbtype));
}
Build Main Parameter Area
foreach (SqlParameter p in arrParams)
{
bool isLast = p == last;
string value = p.Value.ToString();
if (quotedParameterTypes.Contains(p.DbType))
value = "'" + value + "'";
if (p.Direction == ParameterDirection.InputOutput || p.Direction == ParameterDirection.Output)
{
query.Append(string.Format("{0} = {0}_ out{2}\n", p.ParameterName, value, isLast ? "" : ","));
}
else
{
query.Append(string.Format("{0} = {1}{2}\n", p.ParameterName, value, isLast ? "" : ","));
}
}
List Output Parameter results
foreach (SqlParameter p in arrParams.Where(x => x.Direction == ParameterDirection.Output || x.Direction == ParameterDirection.InputOutput))
{
query.Append(string.Format(" select {0}_ {1}\n", p.ParameterName, p.ParameterName.Substring(1)));
}
Full Code:
public static string GetProcedureDebugInformation(SqlCommand cmd, [System.Runtime.CompilerServices.CallerMemberName] string caller = null, [System.Runtime.CompilerServices.CallerFilePath] string filePath = null, [System.Runtime.CompilerServices.CallerLineNumber] int? lineNumber = null)
{
// Collection of parameters that should use quotes
DbType[] quotedParameterTypes = new DbType[] {
DbType.AnsiString, DbType.Date,
DbType.DateTime, DbType.Guid, DbType.String,
DbType.AnsiStringFixedLength, DbType.StringFixedLength
};
// String builder to contain generated string
StringBuilder query = new StringBuilder();
// Build some debugging information using free compiler information
query.Append(filePath != null ? filePath : ""
+ (lineNumber.HasValue ? lineNumber.Value.ToString() : "")
+ (lineNumber.HasValue || !string.IsNullOrWhiteSpace(filePath) ? "\n\n" : ""));
query.Append("\n\n");
var arrParams = new SqlParameter[cmd.Parameters.Count];
cmd.Parameters.CopyTo(arrParams, 0);
// Declare Parameter for output parameters
foreach (SqlParameter p in arrParams.Where(x => x.Direction == ParameterDirection.Output || x.Direction == ParameterDirection.InputOutput))
{
// todo : I only needed a couple of types supported, you could add addition types
string dbtype = string.Empty;
switch (p.DbType)
{
case DbType.Guid:
dbtype = "uniqueidentifier";
break;
case DbType.Int16:
case DbType.Int64:
case DbType.Int32:
dbtype = "int";
break;
case DbType.String:
dbtype = "varchar(max)";
break;
}
query.Append(string.Format(" Declare {0}_ {1}\n", p.ParameterName, dbtype));
}
// Set Exec Text
query.Append(string.Format("\n exec {0}\n", cmd.CommandText));
var last = arrParams.LastOrDefault();
//Build Main Parameter Area
foreach (SqlParameter p in arrParams.OrderByDescending(p => p.ParameterName.Length))
{
bool isLast = p == last;
string value = p.Value.ToString();
if (quotedParameterTypes.Contains(p.DbType))
value = "'" + value + "'";
if (p.Direction == ParameterDirection.InputOutput || p.Direction == ParameterDirection.Output)
{
query.Append(string.Format("{0} = {0}_ out{2}\n", p.ParameterName, value, isLast ? "" : ","));
}
else
{
query.Append(string.Format("{0} = {1}{2}\n", p.ParameterName, value, isLast ? "" : ","));
}
}
// List Output Parameter results
foreach (SqlParameter p in arrParams.Where(x => x.Direction == ParameterDirection.Output || x.Direction == ParameterDirection.InputOutput))
{
query.Append(string.Format(" select {0}_ {1}\n", p.ParameterName, p.ParameterName.Substring(1)));
}
return query.ToString();
}

How to Add a command/SQL statement to a strongly typed TableAdapter's Update/Insert command?

See this question. I have the following code that executes against a SQLIte database using a strongly typed dataset.
messagesAdapter.Update(messages);//messages is a DataTable
var connection = messagesAdapter.Connection;
var retrieveIndexCommand= connection.CreateCommand();
retrieveIndexCommand.CommandText = #"Select last_insert_rowid()";
connection.Open();
var index = retrieveIndexCommand.ExecuteScalar();
connection.Close();
This does not work as the last_inser_rowid() always returns zero. This caused by the fact that it needs to be called during the same connection that is used by the TableAdapter's Update command. How can I change the the TableAdapter's Insert or Update command so that it return the index?
If you are inserting a single row, you can use this:
// cast if necessary
using (var insert = (SQLiteCommand)this.Adapter.InsertCommand.Clone()) {
insert.CommandText += "; SELECT last_insert_rowid()";
foreach (SQLiteParameter parameter in insert.Parameters) {
parameter.Value = row[parameter.SourceColumn];
}
}
var index = Convert.ToInt32(insert.ExecuteScalar());
You can also use it to insert multiple rows and assign your id to each one:
using (var insert = (SQLiteCommand)this.Adapter.InsertCommand.Clone())
{
insert.CommandText += "; SELECT last_insert_rowid()";
// this filter only added rows
foreach (MyDataSet.MessageRow row in messages.GetChanges(DataRowState.Added))
{
foreach (SQLiteParameter parameter in insert.Parameters)
{
parameter.Value = row[parameter.SourceColumn];
}
// use the name of your rowid column
row.ID = Convert.ToInt32(insert.ExecuteScalar());
row.AcceptChanges();
}
}
// then you can perfom the other updates
messagesAdapter.Update(messages);
Note: Be sure to open / close your connection

Resources