Multiple parameter values - sql

I have a problem with BIRT when I try to pass multiple values from report parameter.
I'm using BIRT 2.6.2 and eclipse.
I'm trying to put multiple values from cascading parameter group last parameter "JDSuser". The parameter is allowed to have multiple values and I'm using list box.
In order to be able to do that I'm writing my sql query with where-in statement where I replace text with javascript. Otherwise BIRT sql can't get multiple values from report parameter.
My sql query is
select jamacomment.createdDate, jamacomment.scopeId,
jamacomment.commentText, jamacomment.documentId,
jamacomment.highlightQuote, jamacomment.organizationId,
jamacomment.userId,
organization.id, organization.name,
userbase.id, userbase.firstName, userbase.lastName,
userbase.organization, userbase.userName,
document.id, document.name, document.description,
user_role.userId, user_role.roleId,
role.id, role.name
from jamacomment jamacomment left join
userbase on userbase.id=jamacomment.userId
left join organization on
organization.id=jamacomment.organizationId
left join document on
document.id=jamacomment.documentId
left join user_role on
user_role.userId=userbase.id
right join role on
role.id=user_role.roleId
where jamacomment.scopeId=11
and role.name in ( 'sample grupa' )
and userbase.userName in ( 'sample' )
and my javascript code for that dataset on beforeOpen state is:
if( params["JDSuser"].value[0] != "(All Users)" ){
this.queryText=this.queryText.replaceAll('sample grupa', params["JDSgroup"]);
var users = params["JDSuser"];
//var userquery = "'";
var userquery = userquery + users.join("', '");
//userquery = userquery + "'";
this.queryText=this.queryText.replaceAll('sample', userquery);
}
I tryed many different quote variations, with this one I get no error messages, but if I choose 1 value, I get no data from database, but if I choose at least 2 values, I get the last chosen value data.
If I uncomment one of those additional quote script lines, then I get syntax error like this:
The following items have errors:
Table (id = 597):
+ An exception occurred during processing. Please see the following message for details: Failed to prepare the query execution for the
data set: Organization Cannot get the result set metadata.
org.eclipse.birt.report.data.oda.jdbc.JDBCException: SQL statement does not return a ResultSet object. SQL error #1:You have an error in
your SQL syntax; check the manual that corresponds to your MySQL
server version for the right syntax to use near 'rudolfs.sviklis',
'sample' )' at line 25 ;
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to
your MySQL server version for the right syntax to use near
'rudolfs.sviklis', 'sample' )' at line 25
Also, I should tell you that i'm doing this by looking from working example. Everything is the same, the previous code resulted to the same syntax error, I changed it to this script which does the same.
The example is available here:
http://developer.actuate.com/community/forum/index.php?/files/file/593-default-value-all-with-multi-select-parsmeter/
If someone could give me at least a clue to what I should do that would be great.

You should always use the value property of a parameter, i.e.:
var users = params["JDSuser"].value;
It is not necessary to surround "userquery" with quotes because these quotes are already put in the SQL query arround 'sample'. Furthermore there is a mistake because userquery is not yet defined at line:
var userquery = userquery + users.join("', '");
This might introduce a string such "null" in your query. Therefore remove all references to userquery variable, just use this expression at the end:
this.queryText=this.queryText.replaceAll('sample', users.join("','"));
Notice i removed the blank space in the join expression. Finally once it works finely, you probably need to make your report input more robust by testing if the value is null:
if( params["JDSuser"].value!=null && params["JDSuser"].value[0] != "(All Users)" ){
//Do stuff...
}

Related

How can use executeQueryWithParameters with SQLBuilderSelectExpression to join an x++/sql statement in Microsoft Dynamics?

In Dynamics 365 for Finance and Operations, they describe a method of creating SQL statements "as objects, as opposed to text", but this is somewhat of a lie. They use the objects to create the text which then populates str sqlStatement = selectExpr.getExpression(null);
This sqlStatement would then feed the obsolete statement.executeQuery(sqlStatement);.
I can make the warning go away by using executeQueryWithParameters() with an empty map (SqlParams::create()) as the second parameter, but this seems to be "cheating".
Is there a way I can/should refactor the following to populate the map correctly?
SQLBuilderSelectExpression selectExpression = SQLBuilderSelectExpression::construct();
selectExpression.parmUseJoin(true);
SQLBuilderTableEntry vendTable = selectExpression.addTableId(tableNum(VendTable));
SQLBuilderTableEntry dirPartyTable = vendTable.addJoinTableId(tableNum(DirPartyTable));
SQLBuilderFieldEntry accountNum = vendTable.addFieldId(fieldNum(VendTable, AccountNum));
SQLBuilderFieldEntry name = dirPartyTable.addFieldId(fieldNum(DirPartyTable, Name));
SQLBuilderFieldEntry dataAreaId = vendTable.addFieldId(fieldNum(VendTable, dataAreaId));
SQLBuilderFieldEntry blocked = vendTable.addFieldId(fieldNum(VendTable, Blocked));
vendTable.addRange(dataAreaId, curext());
vendTable.addRange(blocked, CustVendorBlocked::No);
selectExpression.addSelectFieldEntry(SQLBuilderSelectFieldEntry::newExpression(accountNum, 'AccountNum'));
selectExpression.addSelectFieldEntry(SQLBuilderSelectFieldEntry::newExpression(name, 'Name'));
str sqlStatement = selectExpression.getExpression(null);
// FIXME:
ResultSet resultSet = statement.executeQueryWithParameters(sqlStatement, SqlParams::create());
Below is how you would write your code as a standard X++ query. However, I must note that what you're doing may not be the best approach.
DirPartyTable is a special table in AX as it supports inheritance, so you should make sure you fully understand the framework. See:
https://learn.microsoft.com/en-us/dynamicsax-2012/appuser-itpro/implementing-the-global-address-book-framework-white-paper
https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/fin-ops/organization-administration/overview-global-address-book
Code:
VendTable vendTable;
DirPartyTable dirPartyTable;
while select AccountNum from vendTable
where vendTable.Blocked == CustVendorBlocked::No
// DataAreaId along with Partition, are automatically included in the query context depending
// on the company context you're executing the code from
// && vendTable.dataAreaId == curext()
join Name from dirPartyTable
where dirPartyTable.RecId == vendTable.Party
{
info(strFmt("Account: %1; Name: %2", vendTable.AccountNum, dirPartyTable.Name));
}
Regarding an AOT query, look in the AOT at \Queries\VendTableListPage and expand the data sources and learn from it.
Regardless of what OP is trying to do with the query, the answer to the question of "how do I correctly replace executeQuery with executeQueryWithParameters" can be found in the following article.
https://learn.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/dev-ref/query-with-parameters
The new *WithParameters APIs were introduced as a way to mitigate sql injection attacks which may occur when building up sql strings manually with un-sanitized sql parameters as input.
Snippet of the code example from above doc shows how to correctly populate the map to match the sql statement:
str sql = #"
UPDATE Wages
SET Wages.Wage = Wages.Wage * #percent
WHERE Wages.Level = #Level";
Map paramMap = SqlParams::create();
paramMap.add('percent', 1.1); // 10 percent increase
paramMap.add('Level', 'Manager'); // Management increase
int cnt = statement.executeUpdateWithParameters(sql, paramMap);

CodeIgniter query from sql

How can I transform this sql to codeigniter query? I have screenshot of an EER diagram to help you understand better. So there are three tables to join. I guess, one is "pjesma", then "izvodjac", and "izvodi_pjesmu". This sql works when I run it and gives me results I want. I am also using pagination so I need limit and offset somehow included.
SELECT pjesma_id, naslov, naziv
FROM pjesma p, izvodjac i, izvodi_pjesmu ip
WHERE p.pjesma_id = ip.pjesma_pjesma_id
AND i.izvodjac_id = ip.izvodjac_izvodjac_id
in model:
public function paginacija_pjesme($limit, $offset) {
$this->db->select('pjesma_id', 'naslov', 'naziv');
$this->db->from('pjesma p');
$this->db->join('izvodi_pjesmu ip', 'p.pjesma_id=ip.pjesma_pjesma_id');
$this->db->join('izvodjac i', 'i.izvodjac_id=ip.izvodjac_izvodjac_id');
$this->db->limit($limit, $offset);
$query = $this->db->get();
return $query->result();
}
EDIT:
So in select I used wrong syntax, this line:
$this->db->select('pjesma_id', 'naslov', 'naziv');
should be like this:
$this->db->select('pjesma_id, naslov, naziv');
A few things, as you are dealing with objects within the query builder class, you can method-chain and make things a little less cluttered.
You are maybe getting an ambiguous column error, joining and not prefixing your select. Hard to tell without the error being posted you are facing.
Always best to (just in case) set defaults to your method arguments as well, in case you pass a blank variable (or don't need to for whatever reason).
When you are using multiple tables in the FROM statement you are actually doing a CROSS JOIN, and your new code is giving INNER JOIN,trying the join syntax direct to your SQL server might help as you are not actually doing the same thing between your first written query, and the codeigniter one..
Try the below with LEFT join just to see... If there are NULL joins using INNER they will be omitted
public function paginacija_pjesme($limit = 10, $offset = 0) {
$query = $this->db->select('p.pjesma_id, p.naslov, i.naziv')
->from('pjesma p')
->join('izvodi_pjesmu ip', 'p.pjesma_id = ip.pjesma_pjesma_id', 'left')
->join('izvodjac i', 'i.izvodjac_id = ip.izvodjac_izvodjac_id', 'left')
->limit($limit, $offset)
->get();
return $query->result();
}
Are you getting any errors? what do you see if you print_r($query->result()) ?
try also spitting out $this->db->last_query() - this will output the SQL codeigniter has build. Then running this directly to your database, and see the results from there. You might even see the issue without needing to run it.
This is an example of what your current codeigniter code is generating (as you can see, different to your original query):
SELECT pjesma_id, naslov, naziv
FROM pjesma p
INNER JOIN izvodi_pjesmu ip ON p.pjesma_id = ip.pjesma_pjesma_id
INNER JOIN izvodjac i ON i.izvodjac_id = ip.izvodjac_izvodjac_id
# LIMIT 10,0

PYTHON - Using double quotes in SQL constant

I have a SQL query entered into a constant. One of the fields that I need to put in my where clause is USER which is a key word. To run the query I put the keyword into double quotes.
I have tried all of the suggestions from here yet none seem to be working.
Here is what I have for my constant:
SELECT_USER_SECURITY = "SELECT * FROM USER_SECURITY_TRANSLATED WHERE \"USER\" = '{user}' and COMPANY = " \
"'company_number' and TYPE NOT IN (1, 4)"
I am not sure how to get this query to work from my constant.
I also tried wrapping the whole query in """. I am getting a key error on the USER.
SELECT_USER_SECURITY = """SELECT * FROM USER_SECURITY_TRANSLATED WHERE "USER" = '{user}' and
COMPANY = 'company_number' and TYPE NOT IN (1, 4)"""
Below is the error I am getting:
nose.proxy.KeyError: 'user'
So the triple quoted solution was the best one. The problem I was running into was I had not included the "user" key in my dictionary of params which formatted the query.

Active record query failed - Escape quote from query

Background
Framework: Codeignighter/PyroCMS
I have a DB that stores a list of products, I have a duplicate function in my application that first looks for the common product name so it can add a 'suffix' value to the duplicated product.
Code in my Products model class
$product = $this->get($id);
$count = $this->db->like('name', $product->name)->get('products')->num_rows();
$new_product->name = $product->name . ' - ' . $count;
On the second line the application fails only when the $product->name contains quotes.
I was with the understanding that Codeignighter escaped all strings so I dont know why I get this error.
So I tried to use MySQL escape string function but that didn't help either.
The Error Message
A Database Error Occurred
Error Number: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 's Book%'' at line 3
SELECT * FROM `products` WHERE `name` LIKE '%Harry\\'s Book%'
var_dump
Below is the output of doing a var_dump on product->name before and after the line in question;
string 'Harry's Book' (length=12)
A Database Error Occurred
Error Number: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 's Book%'' at line 3
SELECT * FROM `products` WHERE `name` LIKE '%Harry\\'s Book%'
Let's do some testing about this.
Here is what you are doing
$count = $this->db->like('name', $product->name)->get('products')->num_rows();
And i suspect $product->name contains this.
Harry's Book
As we know this is coming from the database table as you are using.
Where you are using the upper query mentioned it is wrapping it with
single quotes and producing this result.
SELECT * FROM `products` WHERE `name` LIKE '%Harry\\'s Book%'
As you see it is escaping apostrophy to tell it is not end of string
Therefore escaping it with two slashes.One for apostrophy and one for being in single quote.
What you have to do is
Before assigning the parameter to query wrap it with double quotes.
$product_name = "$product->name";
And now pass it to query.
$count = $this->db->like('name', $product_name)->get('products')->num_rows();
The output will be this
SELECT * FROM `products` WHERE `name` LIKE '%Harry\'s Book%'
You see the differece here. It contains single slash now and the record will
be found.
Other answers didn't work for me, this does though:
$count = $this->db->query("SELECT * FROM `default_firesale_products` WHERE `title` LIKE '".addslashes($product['title'])."'")->num_rows();
Whenever CI Active Record mangles your queries you can always just put a raw query in instead and have full control.
Try this, using stripslashes() around $product->name:
$count = $this->db->like('name', stripslashes($product->name))->get('products')->num_rows();
CI automatically escapes characters with active records but I bet that it's already escaped if you entered it previously via active record in CI. So now it is doing a double escape.
Update: You may also want to try adding the following before you query:
$this->db->_protect_identifiers = FALSE;
Last try: try querying this way since it seems like the like active record is causing the error:
$like = $product->name;
$this->db->query("SELECT * FROM `products` WHERE `name` LIKE '%$like%'");

Hibernate createSQLQuery and Toad SQL query return different results - parameter problems?

I'm a newbie at Hibernate so excuse me if some of this is glaringly obvious but it's been a very, very long day. I am trying to create and execute a simple query in Hibernate and Toad/Oracle.
The Toad/Oracle sql reads:
select
count(*)
from
fpps_owner.fee_claim_payment_lines l,
fpps_owner.fee_claim_payments p
where
l.fee_claim_payment_id = p.fee_claim_payment_id and
p.claim_index = 87167895
The above returns 10 records, which is correct
The following Java code returns 0 records, which is NOT correct
String sLinesAvailable =
"select count(*) from " +
"fpps_owner.fee_claim_payment_lines l, fpps_owner.fee_claim_payments p " +
"where " +
"l.fee_claim_payment_id = p.fee_claim_payment_id and p.claim_index = :id";
Query qLinesAvailable = em.createNativeQuery(sLinesAvailable);
qLinesAvailable.setParameter("id", "87167895"); // fails
qLinesAvailable.setParameter("id", 87167895); // fails
List<Object> out = (List<Object>) qLinesAvailable.getResultList();
BigDecimal x = (BigDecimal) out.get(0);
Returns 0 records. Using .getSingleResult() also returns 0 records.
What am I missing here?
Any help would be GREATLY appreciated!
If you are not seeing any malformed query errors, it seems like the parameter is not binding correctly.
To debug, I'd print out that SQL statement the line after you set the parameter. This is the only way you can see the SQL after the parameter is set in order to compare it with Toad.
What does your binding file look like? Maybe you have a different name in there for the ID, so it's not able to find it based on the name. Trying binding with the parameter's order value, just as a test.
This might give some ideas: http://www.mkyong.com/hibernate/hibernate-parameter-binding-examples/
Best of luck! We've all been there :)
What happens when you try:
(Number) query.getSingleResult();
Your query isn't returning a list, but rather just a count.
Good luck.