TAG= 'Token line number = 1,Token line offset = 29,Token in error = FROM ' ... insert data from one column to another column of other table - sql

Well... I have two tables named : "chefs" and "cust_Data".
I want to :
Put comments from cust_Data that are being posted into the comment column in chefs table.
By being posted means-> M giving a comment section so that customers will put their comments in "comment" column in "cust_Data" and as soon as those comments are in cust_Data...
Put those comment in "comments" column in "chefs" table.
RAZOR CODE:
#{
var db = Database.Open("vendors");
var selectCommand = "SELECT dish FROM chefs WHERE ID= #0";
var chefID = Request.QueryString["chefid"];
var selectedData = db.Query(selectCommand, chefID);
var dishName=Request.QueryString["dish"];
var chefName=Request.QueryString["chefName"];
var comments=Request["SELECT comments from chefs"]; //IMPORTANT
var ID=Request["SELECT ID from chefs"]; //IMPORTANT
var grid = new WebGrid(source: selectedData, rowsPerPage: 10);
Validation.RequireField("cust_fname", "You must enter your firstname");
Validation.RequireField("cust_lname", "You must enter your surname");
Validation.RequireField("cust_email", "You haven't entered a valid Email_ID");
Validation.RequireField("rating", "Rating is required");
Validation.RequireField("comment", "Please provide your Comment about Respective Homeschef");
var cust_fname = "";
var cust_lname= "";
var cust_email= "";
var rating= "";
var comment= ""; //IMPORTANT
if(IsPost && Validation.IsValid() && chefID.AsInt()!=0){
cust_fname = Request.Form["cust_fname"];
cust_lname = Request.Form["cust_lname"];
cust_email = Request.Form["cust_email"];
rating = Request.Form["rating"];
comment = Request.Form["comment"]; // IMPORTANT->TAKING COMMENT FROM USER
var insertCommand = "INSERT INTO cust_Data (cust_fname, cust_lname, cust_email, dish, chef_ID, rating, comment) Values(#0, #1, #2, #3, #4, #5, #6)";
db.Execute(insertCommand,cust_fname,cust_lname, cust_email, dishName, chefID, rating, comment); // EXECUTED SUCCESSFULLY IN cust_Data
var insert= "INSERT INTO chefs(comments) FROM cust_Data(comment) WHERE chefs(ID)=cust_Data(chef_ID) Values(#0,#1,#2,#3)"; //IMPORTANT
db.Execute(insert,comments,comment,ID,chefID); // IMPORTANT -> ERROR OCCURED ?????????
}
}
Exception Details: System.Data.SqlServerCe.SqlCeException: There was an error parsing the query. [ Token line number = 1,Token line offset = 29,Token in error = FROM ]
I inserted IMPORTANT TAG(to save your time for important things) from where i took the parameters I needed to parse.
Again, Thank you so much in advance...

Though this is not a complete answer, writing this as a answer as the content for explanation is too long.
Even though you've updated the insert into command, the select statement is still wrong. You are trying to write the select statement using the syntax of insert statement i.e. table_name(column_name) but it should be
SELECT column_name from table_name WHERE table_name.column_name=''
Insert into statement works by taking complete SQL select statement prefixed by Insert Into clause. So, your code should be something like this:
INSERT INTO chefs(comments) SELECT comments from cust_Data WHERE chefs.ID=cust_Data.chef_ID
But this won't work as you've not joined the table chefs and cust_data. So you will have to join both the tables and get the correct records, then use the insert into command to insert the records into the chefs table.
Looking more into your program, it looks like you want to update the existing records from the chefs table, or insert is the correct one? Your chefs table has other columns i.e. ID,dish which have been ignored in the insert statement. I doubt that this insert statement would run properly without these columns.
Also, why are you querying comments and ID values separately. And the rows are also not filtered, so it will fetch all the records from the database.
var comments=Request["SELECT comments from chefs"]; //IMPORTANT
var ID=Request["SELECT ID from chefs"]; //IMPORTANT
The database structure and your agenda that you are trying to achieve looks weird to me. I.e. Customer enters the data in cust_data.comments and you want to move/copy these comments to chefs.comment and as soon as the data comes in cust_data table. Why not directly insert into the chefs table instead of this 2 step approach.
Have you thought about the whole process from start to finish? Have you drawn it on paper or screen using UML diagram/process flow?
It looks like you do not have enough experience on the database side. My suggestion would be that you first try these statements directly on the database tool SSMS, get it confirmed that it's working and then apply it in your program. You can use hard coded values for testing and then substitute with parameters when applying it into the program.
Also it would help you if you can learn Stored Procedures and use that in your program. This will reduce such complications from program side and also reduce the database calls

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);

cfsavecontent display double apostrophe in SQL statement

I have several OR in my SQL statement so I want to save a chuck of it in a cfsavecontent. Here is that part:
<cfsavecontent variable="checkDepartment">
<cfif #wrkDept# EQ #dept[2][1]#>
Department = 'Health' AND
<cfelse>
Department = '#wrkDept#' AND
</cfif>
</cfsavecontent>
But the error I get on the page shows 2 sets of apostrophes around the word Health.
SQL
SELECT COUNT(*) AS numItems
FROM IT_PROJECTS
WHERE
Department = ''Health'' AND
status = 'Cancelled'
Can anyone help me to only get a single apostrophe? Thanks
So this answer seems a lot more complicated than it really is. And without knowing specifically what your query looks like (re:OR conditions), I'm not really sure how to structure it. It can be better. The goal should be to make one single trip to your SQL server with the query that makes the most sense for the data you're trying to get. I'm not sure what you are trying to do with cfsavecontent, but I don't think you need it.
The bulk of my example query (https://trycf.com/gist/4e1f46bfa84a6748aced0f9ee8221c6d/acf2016?theme=monokai) is setup. I chose to go with a cfscript format, because as Redtopia said, I also find it much easier to build a dynamic query in cfscript.
After initial setup, I basically just script out the variables I'll use in my final queryExecute().
// Base query.
qry = "SELECT count(*) AS theCount FROM IT_PROJECTS WHERE 1=1 " ;
// This is our dynamic filter that we build below.
qfilter = {} ;
// Query options.
opts = { "dbtype":"query" } ;
After we have our base, I build up the dynamic part of the query. This is the part that will likely change quite a bit depending on your current needs and setup.
For the first part, I basically replaced your cfif with a ternary evaluation. I'm not sure how your data plays into the evaluation of dept or where that array comes from. But from there I build a basic included statement of the query and set up the queryparam values for it. Then I add a second check that will pick a different set of values for the query (currently based on even/odd seconds). Again, I'm not sure of the intent of your query here, so I just made something dynamic.
//////////// BUILD DYNAMIC FILTER ////////////
qdept = ( wrkDept == dept[2][1] ) ? 'Health' : wrkDept ;
/// This one is an included filter:
qry &= " AND department = :dpt AND status = :sts " ;
qfilter.dpt = {"value":qdept,"cfsqltype":"CFSQLVARCHAR"} ;
qfilter.sts = {"value":"Cancelled","cfsqltype":"CFSQLVARCHAR"} ;
/// Adding Dynamic ORs
// Dynamically set status based on even/odd seconds.
qStatus = ( now().second()%2==0) ? "Cancelled" : "Active" ;
qry &= " OR ( department = :dpt2 AND status = :sts2 ) " ;
qfilter.dpt2 = {value:"IT",cfsqltype:"CFSQLVARCHAR"} ;
qfilter.sts2 = {value:qStatus,cfsqltype:"CFSQLVARCHAR"} ;
This gives us a SQL string that looks like:
SELECT count(*) AS theCount
FROM IT_PROJECTS
WHERE 1=1
AND department = :dpt AND status = :sts
OR
( department = :dpt2 AND status = :sts2 )
With a SQL statement, the placement of AND and OR conditions can greatly impact the results. Use parenthesis to group conditions how you need them.
After we've built the query string, we just have to plug it and our queryparams into the queryExecute().
result = queryExecute( qry , qfilter , opts ) ;
And if we want to output our data, we can go:
writeOutput("There are " & result.theCount & " records." ) ;
Which gives us:
There are 8 records.
Again, I don't know what your main conditions look like. If you can give me an example of a query with a bunch of ORs and ANDs, I'll try to modify this for you.

How to query ODBC with Dapper with multiple parameters including a WHERE IN?

I've hit an issue using Dapper to query an ODBC provider. The query in question is supplied several parameters. One of the parameters is used to populate a WHERE IN operator.
So far I've tried supplying the query with: DynamicParameters, ? regular parameters, ?name? pseudo-positional parameters and some combinations of these.
SELECT companyId
,projectId
,contractId
,status
FROM certificate
WHERE companyId = ?companyId?
AND projectId = ?projectId?
AND contractId = ?contractId?
AND invoiceId IN ?invoiceIds?
var results = await connection
.QueryAsync<Certificate>(query, new { companyId, projectId, contractId, invoiceIds = new string[] { '1a', '1b', '2a' }});
Expected results are several rows being returned. If I hardcode the query with it's parameters it works fine, so the data I'm supplying should return rows.
Instead I'm getting an exception with the following message:
ERROR [07001] [DataDirect][ODBC Progress OpenEdge Wire Protocol driver]Value has not been specified for parameter 4.
ERROR [07001] [DataDirect][ODBC Progress OpenEdge Wire Protocol driver]Value has not been specified for parameter 5.
If that is your code, then your code doesn't compile. You are not supplying any values for the first three parameters and you are giving illegal characters instead of string in the fourth parameter. I see no reason why this shouldn't work:
var results = await connection
.QueryAsync<Certificate>(query,
new { companyId=1, projectId=1, contractId=1, invoiceIds = new [] { "1a", "1b", "2a" }});

Multiple parameter values

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...
}

Dynamic spinner using a SQLite Database

I want my spinner to be dynamically updated from my SQLite database. The spinner should contain months and years (ex. april 2013), from my sqlite database.
I have searched the web a lot, and also many of the questions from this site, but now i can't solve the rest.
Right now my spinner list is getting longer, but there is no text? What is the problem?
Here is the relevant code in my main class
KilometerSQL info = new KilometerSQL(this);
info.open();
String data = info.getData();
final Cursor cSpinner;
cSpinner = (Cursor) KilometerSQL.getSpinnerData();
startManagingCursor(cSpinner);
SimpleCursorAdapter scaYear = new SimpleCursorAdapter(this, android.R.layout.simple_spinner_item,cSpinner,new String[] {KilometerSQL.KEY_MONTH},new int[]{});
scaYear.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner1.setAdapter(scaYear);
info.close();
tvView.setText(data);
And here is my SQLiteDatabase:
public static Cursor getSpinnerData() {
// TODO Auto-generated method stub
return ourDatabase.query(DATABASE_TABLE, //table name
new String[] {KEY_ROWID, KEY_MONTH}, //list of columns to return
null, //filter declaring which rows to return; formatted as SQL WHERE clause
null,
KEY_MONTH, //filter declaring how to group rows; formatted as SQL GROUP BY clause
null, //filter declaring which row groups to include in cursor; formatted as SQL HAVING clause
null); //how to order rows; formatted as SQL ORDER BY clause
}
Don't hesitate to ask questions if you need some info or code.
Thank you very much.
I found the solution..
I needed to add this into the code: android.R.id.text1
like this:
SimpleCursorAdapter scaYear = new SimpleCursorAdapter(this, android.R.layout.simple_spinner_item,cSpinner,new String[] {KilometerSQL.KEY_MONTH},new int[]{android.R.id.text1});