I am using JdbcTemplate to query the database however i am building a dynamic WHERE clause and i want to escape quotes. Under is an example of how my string looks :
There are times that they would not be any where clause since the user may want to return all records. So using prepared statement may not be feasible here.
JdbcTemplate
String sql = "select crime.*, "+
"criminalSocialSecurityNumber,criminal.fName as criminalFName,criminal.lName as criminalLName,"+
"criminal.photo as criminalPhoto,criminal.dob as criminalDob,victimSocialSecurityNumber,"+
"victim.fName as victimFName,victim.lName as victimLName,victim.photo as victimPhoto, victim.dob as victimDob "+
"from tblcrimes crime "+
"left join tblcriminalcrime on crime.crimeRecNo = tblcriminalcrime.crimeRecNo "+
"left join tblvictimcrime on crime.crimeRecNo = tblvictimcrime.crimeRecNo "+
"inner join tblcitizens criminal on criminal.socialSecurityNumber = tblcriminalcrime.criminalSocialSecurityNumber "+
"inner join tblcitizens victim on victim.socialSecurityNumber = tblvictimcrime.victimSocialSecurityNumber " + where_clause;
Using prepared statement is perfectly possible, and is what you should do.
Build your query dynamically, using placeholders (?) for every argument, and each time you add a placeholder, also add the argument value to a list of arguments. In the end, you have a parameterized SQL query, and a list of argument values to bind to the prepared statement.
Something like
List<Object> args = new ArrayList<Object>();
StringBuilder whereClause = new StringBuilder();
if (criteria.getFoo() != null) {
whereClause.append(" and foo = ?");
args.add(criteria.getFoo());
}
if (criteria.getBar() != null) {
whereClause.append(" and bar = ?");
args.add(criteria.getBar());
}
// ...
PreparedStatement stmt = connection.prepareStatement(query + whereClause);
int i = 1;
for (Object arg : args) {
stmt.setObject(i, arg);
i++;
}
Related
I try recreate SQL view in AOT and I need add compute column which reference view (FISCALCALENDARFLATTENEDVIEW). In the class I cannot retrieved fields for this view. Problem is with "sGREGORIANDATE = " line where I specify a fieldStr(), cannot do it for View. I put SQL statement just to help understand what I try achieve.
CREATE VIEW [dbo].[vw_DimFiscalPeriod] AS
SELECT
T1.RECID AS LEDGERRECID,
T1.PARTITION AS PARTITION,
T1.RECID AS RECID,
T2.CALENDARID AS CALENDARID,
T2.CALENDARRECID AS CALENDARRECID,
T2.GREGORIANDATE AS GREGORIANDATE,
T2.MONTH AS MONTH,
T2.PERIODNAME AS PERIODNAME,
T2.PERIODOFFSET AS PERIODOFFSET,
T2.PERIODRECID AS PERIODRECID,
T2.QUARTER AS QUARTER,
T2.QUARTEROFFSET AS QUARTEROFFSET,
T2.YEARNAME AS YEARNAME,
T2.YEAROFFSET AS YEAROFFSET,
T2.PARTITION AS PARTITION#2,
(CAST ((((T1.RECID) * (100000)) + (DateDiff(d, {ts '1900-01-01 00:00:00.000'}, T2.GREGORIANDATE))) AS NVARCHAR(50))) AS LEDGERGREGORIANDATEID
FROM AXDB.dbo.LEDGER T1
INNER JOIN
AXDB.dbo.FISCALCALENDARFLATTENEDVIEW T2
ON T1.FISCALCALENDAR = T2.CALENDARRECID
AND T1.PARTITION = T2.PARTITION
I created class but for my calculation need fields from both objects and column list for a view is not supported. sRECID is ok but sGREGORIANDATE definition is not.
public class vw_DimFiscalPeriod extends common
{
private static server str GregoriandDateID()
{
str sReturn,
str sRECID,
str sGREGORIANDATE;
DictView dictView;
dictView = new DictView(tableNum(vw_DimFiscalPeriod));
sRECID = dictView.computedColumnString(tableStr(Ledger), fieldStr(RecId),FieldNameGenerationMode::FieldList, true);
sGREGORIANDATE = dictView.computedColumnString(viewstr(FiscalCalendarFlattenedView), fieldStr(GregorinaDate), FieldNameGenerationMode::FieldList, true);
sReturn = "("+RECID+" * 100000) + DateDiff(d, {ts '1900-01-01 00:00:00.000'}, " + sGREGORIANDATE + " )";
return sReturn;
}
}
I think that should work and line for sGREGORIANDATE should looks like that:
sGREGORIANDATE = SysComputedColumn::returnField(tableStr(FiscalPeriodDateView), tableStr(FiscalCalendarFlattenedView), fieldStr(FiscalCalendarFlattenedView, GregorianDate)));
I am having trouble with displaying the results in the search activity of my app. I wonder where it went wrong.
The aim of the function below is to search the input query of the user and find it in every files listed. But the results only matches one data eventhough the query is also present in the other files. Here is the code.
public void searchFiles(File[] filelist, String query, String querysearch, String[] namesOfFiles){
querysearch = "SELECT * FROM Data WHERE ObjectID = ? ";
int temp2 = filelist.length;
for (int i = (temp2-1); i >= 0; i--) {
if(!(filelist[i].getName().equals("DataObjectDB.db")) && !(filelist[i].getName().endsWith("-journal"))){
temp1 = filelist[i].getName();
namesOfFiles[i] = temp1.replaceAll(".db$", "");
Toast.makeText(getApplicationContext(),"Searching " + query + " in: " + namesOfFiles[i], Toast.LENGTH_SHORT).show();
DatabaseHelper db1 = new DatabaseHelper(getApplicationContext(),namesOfFiles[i]);
SQLiteDatabase sqldb = db1.getWritableDatabase();
cursor = sqldb.rawQuery(querysearch, new String[]{query});
Toast.makeText(getApplicationContext(),cursor.toString(), Toast.LENGTH_SHORT).show();
}
}
final ListView listView = (ListView) findViewById(R.id.results_listview);
SearchAdapter adapter = new SearchAdapter(this, R.layout.results_column, cursor,0 );
listView.setAdapter(adapter);
}
The searchFiles() function passes the filelist, query, querysearch and namesOfFiles where 1) filelist contains the list of files in the source folder 2) query is the user input he/she wants to search 3) querysearch is the select statement 3) namesofFiles is just an empty string.
I indicate a toast to see if the code traverses through all the folders. And yes it is. But I don't know why it is not displaying all the results.
Any help? Thanks!
Found an answer on different posts. Basically, you just have to use hashmap and arraylist first before setting up the adapter directly.
I am getting data from these two tables using linq to entities, relationships exist between tables on primary foriegn key basis, result set is coming but every row is repeating multiple times in reult however in Db there are not duplicate rows. Don't understand how to resolve this.
here is piece of code:
StringBuilder sb = new StringBuilder();
string text = txtBoxSearch.Text;
OLSContainer ols = new OLSContainer();
var result = from tex in ols.COURSEs
from another in ols.UNITs
where tex.courseName.Contains(text) || tex.description.Contains(text) || another.unitName.Contains(text)
select new { tex,another };
foreach (var cours in result)
{
sb.AppendLine("<h2 id='" + cours.tex.courseID + "'><a href='admin.aspx?id='" + cours.tex.courseID + "''>" + cours.tex.courseName + "</a></h2>");
}
foreach (var cours in result)
{
sb.AppendLine("<h2 id='" + cours.another.unitID + "'><a href='admin.aspx?id='" + cours.another.unitID + "''>" + cours.another.unitName + "</a></h2>");
}
The problem is this:
var result = from tex in ols.COURSEs
from another in ols.UNITs
It is a cross join. It matches every course with every unit. It doesn't use any FK/PK because no relation (navigation property) is used in this query. To use the relation you have to modify it to:
var result = from tex in ols.COURSEs
from another in tex.SomeNavigationProperty // tex
Im writing SSAS MDX queries involving more than 2 axis' to retrieve a value. Using ADOMD.NET, I can get the returned cellset and determine the value by using
lblTotalGrossSales.Text = CellSet.Cells(0).Value
Is there a way I can get the CellSet's Cell(0) Value in my MDX query, instead of relying on the data returning to ADOMD.NET?
thanks!
Edit 1: - Based on Daryl's comment, here's some elaboration on what Im doing. My current query is using several axis', which is:
SELECT {[Term Date].[Date Calcs].[MTD]} ON 0,
{[Sale Date].[YQMD].[DAY].&[20121115]} ON 1,
{[Customer].[ID].[All].[A612Q4-35]} ON 2,
{[Measures].[Loss]} ON 3
FROM OUR_CUBE
If I run that query in Management Studio, I am told Results cannot be displayed for cellsets with more than two axes - which makes sense since.. you know.. there's more than 2 axes. However, if I use ADOMD.NET to run this query in-line, and read the returning value into an ADOMD.NET cellset, I can check the value at cell "0", giving me my value... which as I understand it (im a total noob at cubes) is the value sitting where all these values intersect.
So to answer your question Daryl, what I'd love to have is the ability to have the value here returned to me, not have to read in a cell set into the calling application. Why you may ask? Well.. ultimately I'd love to have one query that performs several multi-axis queries to return the values. Again.. Im VERY new to cubes and MDX, so it's possible Im going at this all wrong (Im a .NET developer by trade).
Simplify your query to return two axis;
SELECT {[Measures].[Loss]} ON 0, {[Term Date].[Date Calcs].[MTD] * [Sale Date].[YQMD].[DAY].&[20121115] * [Customer].[ID].[All].[A612Q4-35]} ON 1 FROM OUR_CUBE
and then try the following to access the cellset;
string connectionString = "Data Source=localhost;Catalog=AdventureWorksDW2012";
//Create a new string builder to store the results
System.Text.StringBuilder result = new System.Text.StringBuilder();
AdomdConnection conn = new AdomdConnection(connectionString);
//Connect to the local serverusing (AdomdConnection conn = new AdomdConnection("Data Source=localhost;"))
{
conn.Open();
//Create a command, using this connection
AdomdCommand cmd = conn.CreateCommand();
cmd.CommandText = #"SELECT { [Measures].[Unit Price] } ON COLUMNS , {[Product].[Color].[Color].MEMBERS-[Product].[Color].[]} * [Product].[Model Name].[Model Name]ON ROWS FROM [Adventure Works] ;";
//Execute the query, returning a cellset
CellSet cs = cmd.ExecuteCellSet();
//Output the column captions from the first axis//Note that this procedure assumes a single member exists per column.
result.Append("\t\t\t");
TupleCollection tuplesOnColumns = cs.Axes[0].Set.Tuples;
foreach (Microsoft.AnalysisServices.AdomdClient.Tuple column in tuplesOnColumns)
{
result.Append(column.Members[0].Caption + "\t");
}
result.AppendLine();
//Output the row captions from the second axis and cell data//Note that this procedure assumes a two-dimensional cellset
TupleCollection tuplesOnRows = cs.Axes[1].Set.Tuples;
for (int row = 0; row < tuplesOnRows.Count; row++)
{
for (int members = 0; members < tuplesOnRows[row].Members.Count; members++ )
{
result.Append(tuplesOnRows[row].Members[members].Caption + "\t");
}
for (int col = 0; col < tuplesOnColumns.Count; col++)
{
result.Append(cs.Cells[col, row].FormattedValue + "\t");
}
result.AppendLine();
}
conn.Close();
TextBox1.Text = result.ToString();
} // using connection
Source : Retrieving Data Using the CellSet
This is fine upto select on columns and on Rows. It will be helpful analyze how to traverse sub select queries from main query.
I'm trying to do a search on a table in my database where it returns the top 50 rows with a firstname like the search term being passed to the function, but its always returning the same 50 results
My sql looks like this:
Select TOP(50) *
FROM [database].[dbo].[records]
WHERE (A_1STNAME LIKE '" + #searchTerm + "%')
ORDER BY A_RECID
When I run this query in Visual Studios query window, it works as expected but when I run it through my ASP.NET application, it always returns the same 50 results, and only one of them has a first name close to the searchTerm I passed to it.
here is the page code that runs the function:
protected void Page_Load(object sender, EventArgs e)
{
_migrated_data data = new _migrated_data();
DataSet ds = data.Search(Request.QueryString.Get("query"), "A_RECID", 50);
if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
{
rpt_Data.DataSource = ds.Tables[0].DefaultView;
rpt_Data.DataBind();
}
}
and here is the search method of _migrated_data:
public DataSet Search(String #pSearchTerm, String #pSortBy, int #pRowCount)
{
DataSet ds = new DataSet();
OleDbConnection objOleDBConn;
OleDbDataAdapter objOleDBDa;
objOleDBConn = new OleDbConnection(ClearingHouse_OLEDDB);
objOleDBConn.Open();
string lSQL = "SELECT TOP(50) * FROM [database].[dbo].[records]";
lSQL += " WHERE (A_1STNAME LIKE #searchTerm ) ORDER BY #sortBy";
SqlCommand t = new SqlCommand(lSQL);
if (pSearchTerm != null && pSearchTerm != "")
{
t.Parameters.AddWithValue("#searchTerm", #pSearchTerm + "%");
}
if (pSortBy != null && pSortBy != "")
{
t.Parameters.AddWithValue("#sortBy", #pSortBy);
}
else
{
t.Parameters.AddWithValue("#sortBy", "A_RECID");
}
objOleDBDa = new OleDbDataAdapter(t.CommandText, objOleDBConn);
objOleDBDa.SelectCommand.CommandType = CommandType.Text;
objOleDBDa.Fill(ds);
objOleDBConn.Close();
return ds;
}
Using locals to view the final CommandText of t, I get the sql results I gave above.
Any help is greatly appriciated :)
AS Rob Rodi said, first of all, to get the results begining with a value you will need % char at the end of the therm:
Select TOP(50) *
FROM [database].[dbo].[records]
WHERE (A_1STNAME LIKE '" + #searchTerm + "%')
ORDER BY A_RECID
Second, probably your searchTerm is empty, so it's grabbing always the same results.
Debug your app and watch the variable to see if it's receiving some value.
You are having SQL injection there. Also it looks like the %-signs are missing.
The fact, that the query works in a query window and not in your app means, that the error is not in your query! Did you think about that? Probably, you should post code of your ASP.NET app.
It sounds like your parameter isn't being correctly passed to your data layer. Easiest way to find out if that's the case is to turn on Sql Profiler and check to see if it's being passed. If it is, your sql's to blame. If it's not, it's your application. You can then use the debugger on your application to work your way up the stack to see where the problem lies.