I'm making a C++ program that connects to an SQL database. This query is really long and probably not the best way to go about it, but that's besides the point. This error is referring to the first " in this code, right before SELECT. Not sure what the problem is considering the ending " is at the end of the function. I'm assuming that I need to use some escape characters somewhere but nowhere that I put them seem to do anything.
res = stmt->executeQuery("SELECT customers.customerNumber, customers.customerName, customers.phone, customers.creditLimit, orders.orderNumber, orders.orderDate, orders.status, products.productName, orderdetails.quantityOrdered, orde
rdetails.priceEach, employees.firstName, employees.lastName, employees.email
AS returnedInfo
FROM customers
JOIN orders ON customers.customerNumber=orders.customerNumber
JOIN orderdetails ON orders.orderNumber = orderdetails.orderNumber
JOIN products ON orderdetails.productCode = products.productCode
JOIN employees ON customers.salesRepEmployeeNumber = employees.employeeNumber
WHERE customers.customerNumber = \'103\';");
Literal strings needs to end before the line ends. You can work around that by using the preprocessor line-continuation, as in
res = stmt->executeQuery("SELECT customers.customerNumber, customers.customerName, customers.phone, customers.creditLimit, orders.orderNumber, orders.orderDate, orders.status, products.productName, \orderdetails.quantityOrdered, orderdetails.priceEach, employees.firstName, employees.lastName, employees.email \
AS returnedInfo \
FROM customers \
JOIN orders ON customers.customerNumber=orders.customerNumber \
JOIN orderdetails ON orders.orderNumber = orderdetails.orderNumber \
JOIN products ON orderdetails.productCode = products.productCode \
JOIN employees ON customers.salesRepEmployeeNumber = employees.employeeNumber \
WHERE customers.customerNumber = '103';");
Of use the compilers string-literal concatenation where it concatenates adjacend string literals:
res = stmt->executeQuery("SELECT customers.customerNumber, customers.customerName, customers.phone, customers.creditLimit, orders.orderNumber, orders.orderDate, orders.status, products.productName, orderdetails.quantityOrdered, orderdetails.priceEach, employees.firstName, employees.lastName, employees.email "
"AS returnedInfo "
"FROM customers "
"JOIN orders ON customers.customerNumber=orders.customerNumber "
"JOIN orderdetails ON orders.orderNumber = orderdetails.orderNumber "
"JOIN products ON orderdetails.productCode = products.productCode "
"JOIN employees ON customers.salesRepEmployeeNumber = employees.employeeNumber "
"WHERE customers.customerNumber = '103';");
Note that both of these will create what is in reality a single line. If you want to pass it to the function as multiple lines you need to add the newline \n at the end of each "line" yourself. Or use raw string literals as mentioned in the answer by druckermanly.
On a side-note: As you might have noticed, I don't escape the single quoted "string". In double-quoted strings you don't have to escape the single-quote.
You want a raw string literal (introduced in C++11). The problem is that, by default, you can't put an actual newline (instead of \n) in your string, but you can with raw string literals.
If you're not using C++11 or later, you can use other techniques (line continuations, or concatenated sequential strings) but this is often the cleanest way to represent your intent if it's available to you.
Here's an example using your query:
res = stmt->executeQuery(R"SQL(
SELECT
customers.customerNumber,
customers.customerName,
customers.phone,
customers.creditLimit,
orders.orderNumber,
orders.orderDate,
orders.status,
products.productName,
orderdetails.quantityOrdered,
orderdetails.priceEach,
employees.firstName,
employees.lastName,
employees.email
AS returnedInfo
FROM customers
JOIN orders ON customers.customerNumber=orders.customerNumber
JOIN orderdetails ON orders.orderNumber = orderdetails.orderNumber
JOIN products ON orderdetails.productCode = products.productCode
JOIN employees ON customers.salesRepEmployeeNumber = employees.employeeNumber
WHERE customers.customerNumber = '103';
)SQL");
Related
This is my column name and value below.
ASSET_NAME - mats&service
Below is the dax code i use to get data from table and create a link to filter the my page, but it wont work when value(mats&service) in column(ASSET_NAME) has & in it, the link gets terminated at & like this
https:/app.powerbi.com/?filter/somerandomtextand%20andthesemats
and the filter wont work, can someone help me escape this & so that value is accepted and filtered in my page,
RawData =
MAX ('Raw data'[Raw Data])&"?filter=Table/ASSET_NAME eq"&" '"
& MAX ( CurrentData[ASSET_NAME] )&"' and Table/LEVEL1 eq"&" '"
& MAX ( CurrentData[LEVEL])&"' and Table/DOS_NO eq"&" ' "
& MAX ( CurrentData[RULE_NO] )&" ' "
The official documentation has a section how to handle special characters in the values. The & character should be replaced with %26, so instead of mats&service value, try with mats%26service.
When concatenating the strings to construct the URL, use SUBSTITUTE DAX function (or multiple nested or separate calls to it) to replace the special characters in the values, e.g. like this:
Measure =
var AssetName1 = MAX(CurrentData[ASSET_NAME])
var AssetName2 = SUBSTITUTE(AssetName1, "%", "%25")
var AssetName3 = SUBSTITUTE(AssetName2, "+", "%2B")
var AssetName4 = SUBSTITUTE(AssetName3, "&", "%26")
RETURN "?filter=Table/ASSET_NAME eq '" & AssetName4 & "'"
Another option is to add a custom column with "safe" values, which are URL encoded using Uri.EscapeDataString M function:
ASSET_NAME_ENCODED = Uri.EscapeDataString([ASSET_NAME])
and use this column when constructing the URL.
I have a native Oracle query running in an Excel workbook, and I'm passing the user-supplied values from a table into the queries WHERE clause.
I wrote a quick function in M that I think adds single quotes to a string that's passed in
(x) =>
let
string_format = "'" & x & "'"
in
string_format
I apply this function to a column and then transform the column to a list but any strings with embedded commas are surrounded by double quotes
text_tbl3 = Table.TransformColumns(text_tbl2,{{"Org_Names", string_format}})
text_ls = Table.ToList(text_tbl3)
It's difficult to see, but TD,AMERITRADE is surrounded by double and single quotes like this : "'TD, AMERITRADE'". I want it to read 'TD,AMERITRADE' , so it has the same formatting as the other cells, but I cannot figure out what causes the additional double quotes.
Quoting text
quick function in M that I think adds single quotes to a string that's passed in
Your function is correct. & is the text concatenation operator.
Because you're using a single expression, you could simplify it by removing the inner let..in expression. (If you don't open the advanced editor you won't see the outer let..in expression).
quote_text = (string as text) => "'" & string & "'"
Note: Your screenshot has extra quotes
Your inputs were:
CHASE
CITI
"TD, AMERITRADE"
Which is why you end up with:
'CHASE'
'CITI'
'"TD, AMERITRADE"'
Your cell probably has quotes on "TD, AMERITRADE" but not on the others.
Getting a comma separated list as a single string
Text.Combine(list, separator=", ") will create a string like a CSV file.
let
list_names = table3[Company],
// equivalent to: list_names = {"CHASE", "CITI", "TD, AMERITRADE"},
without_quotes = Text.Combine(list_names, ", "),
list_quoted = List.Transform(
list_names,
quote_text
),
with_quotes = Text.Combine(list_quoted, ", "),
results = [
list_names = list_names,
list_quoted = list_quoted,
string_without_quotes = without_quotes,
string_with_quotes = with_quotes,
without_equal_to = "string = ""CHASE, CITI, TD, AMERITRADE""",
with_equal_to = "string = ""'CHASE', 'CITI', 'TD, AMERITRADE'"""
]
in
results
How do we use that string in a native query?
My query uses SQL but the method is the same for Oracle.
raw_sql_query is your raw query. It uses the parameter #Company
sql_parameters is a Record type that declares all parameters you are using. Here we use your string with the qoute_text function.
Value.NativeQuery inserts the parameters for you.
let
company = "TD, AMERITRADE",
raw_sql_query = "
select * from Table
where Company = #Company
",
sql_parameters = [
Company = quote_text( company )
],
source = Sql.Database(
"localhost",
"Adventure Works"
),
results = Value.NativeQuery(
source,
raw_sql_query,
sql_parameters
)
in
results
How do we test whether the string function is quoting correctly?
First create a new blank query. We call quote_text() to verify the output.
I used a Record named results so you can label and view every value on a single screen.
manual_quote uses the string concatenation operator to quote strings
quote_string( sample_string ) inserts variables into a text template. Both return the exact same string.
Text.Format becomes cleaner the more complicated your template becomes. This function is simple enough it's not necessary.
Your original function
This is what your function in the advanced editor looks like:
let
quote_text = (x) =>
let
string_format = "'" & x & "'"
in
string_format
in
quote_text
You may remove the inner let
let
quote_text_simple = (string as text) =>
"'" & string & "'"
in
quote_text_simple
How you can use optional arguments and string Templates
let
// a custom function to Surround a string with single quotes.
// A optional second argument lets you specify a different character
quote_string = (input_string as text, optional character as text) =>
let
character = if character = null then "'" else character,
template = "#[quote]#[string]#[quote]",
quoted_string = Text.Format(
template,
[
quote = character,
string = input_string
]
)
in
quoted_string
in
quote_string
I have a search requirement.
For example, I am want to search a word "Microsoft Account" in a large content.
In the large text, it may be defined like
"Microsoft_Account" or "Microsoft-Account".
My search logic should identify the above words also.
Is there any way to implement this using regular expression?
(can be done by splitting and loop search but would be great if any solution using regular expression)
If you just need the regEx, it's : a[ -_]b
Where a and b are the two part of what you search
If you need an algo :
You need to first split you search word (in many language this yourString.split(regex)) whit th regex spliter : [ -_] that will allow the three different caracter.
In many cas, split return a table of string. So then you have to look in your table to recreate your regex.
Algorithm
str = your_search_string
tab_string = str.split("[ -_]")
res = ""
foreach part in tab_string
res = res + part + "[ -_]"
endForeach
res = res[0 length-5] //to remove "[ -_]" at the end
with this little algorithm you will have for your exemple :
str = "Microsoft Account"
tab_string = ["Microsoft", "Account"]
res = ""
forEach
| res = "Microsoft[ -_]"
| res = "Microsoft[ -_]Account[ -_]"
EndforEach
res = "Microsoft[ -_]Account"
This is my code:
$db = new COM("ADODB.Connection");
$dsn = "DRIVER={SQL Server}; SERVER={$server}; UID={$usr}; PWD={$pwd}; DATABASE={$dbname}";
$db->Open($dsn);
$sql = "SELECT o.CardCode, o.CardName, o.VatIDNum, o.AddID, o.Cellular, o.E_Mail, c.Address
FROM ocrd o INNER JOIN crd1 c ON o.CardCode = c.CardCode
WHERE o.Cellular = '$phone1' o.CardName LIKE N'%$lname%'";
$result = $db->execute($sql);
In the databese the o.Cellular column includes phone numbers that could be formatted with dashes/spaces/+ sign/braces so when I am checking WHERE o.Cellular = '$phone1' I need to reformat o.Cellular to only digits (the $phone1 already only digits).
The second problem is that if o.Cellular not equals $phone1, I want to check o.CardName LIKE N'%$lname%'.
So the current part of code doesn't works as I need.
Any help please...
REGEX is extremely limited in SQL Server. Here's an example to replace the following characters in your phone number: + ( ) - \s
SELECT
o.CardCode,
o.CardName,
o.VatIDNum,
o.AddID,
o.Cellular,
o.E_Mail,
c.Address
FROM
ocrd o
INNER JOIN
crd1 c ON
o.CardCode = c.CardCode
WHERE
replace(replace(replace(replace(replace(o.Cellular,'-',''),' ',''),'(',''),')',''),'+','') = '$phone1'
or o.CardName LIKE N'%$lname%'
--test example you can run to see the results of the code
declare #Cellular varchar(16) = '+1 (156) 555-7899'
select replace(replace(replace(replace(replace(#Cellular,'-',''),' ',''),'(',''),')',''),'+','')
--returns 1156555789
My own final solution:
$phone1 = "0123456789"; /* tests 0123456789 */
$phone1 = preg_replace("/\D+/", "", $phone); /* Leave digits only */
$phone1_wildcard = "%".implode("%",str_split($phone1))."%"; /* converts 0123456789 to %0%1%2%3%4%5%6%7%8%9% in order to catch any mistyping in mssql */
Is it possible to change this #NamedQuery query:
SELECT #rownum:=#rownum+1 'no', m.title, m.author, REPLACE(SUBSTRING_INDEX(m.content, ' ', 20), '<br>', ' '), m.viewed, m.hashid FROM book m, (SELECT #rownum:=0) r WHERE m.lang = ?1 AND m.title like CONCAT('%',?2,'%') ORDER BY m.title asc
to a CriteriaBuilder equivalent. Or not?...
I think the natural way to do this would be to handle the query in JPA, but to do the numbering and string mangling in Java. The query looks like this:
EntityManagerFactory emf;
String lang;
String keyword;
CriteriaBuilder builder = emf.getCriteriaBuilder();
final CriteriaQuery<Book> criteria = builder.createQuery(Book.class);
Root<Book> root = criteria.from(Book.class);
criteria.where(builder.and(builder.equal(root.get(Book_.lang), lang), builder.like(root.get(Book_.title), ("%" + keyword + "%"))));
criteria.orderBy(builder.asc(root.get(Book_.title)));
Since the results come back in a list, you can simply use the index into the list for the 'no' field, and you can write a method getContentSnippet() on Book to do the substringing and replacement.
If you really wanted to do the string mangling in the database, perhaps to reduce the amount of text transferred, then you could write a tuple query, which could retrieve the book and the snippet. Note that i would still retrieve the whole book, rather than individual fields, because this makes subsequent programming so much easier; if you want to avoid having the whole content transferred, mark it for lazy loading in the Book class. The query looks like:
CriteriaBuilder builder = emf.getCriteriaBuilder();
final CriteriaQuery<Tuple> criteria = builder.createTupleQuery();
final Root<Book> root = criteria.from(Book.class);
final Expression<String> snippetExpr = builder.substring(root.get(Book_.content), 1, 120);
criteria.multiselect(root, snippetExpr);
criteria.where(builder.and(builder.equal(root.get(Book_.lang), lang), builder.like(root.get(Book_.title), ("%" + keyword + "%"))));
criteria.orderBy(builder.asc(root.get(Book_.title)));
I'm using substring to build the snippet, because i'm using PostgreSQL, and that doesn't have an equivalent of the SUBSTRING_INDEX function. You could use CriteriaBuilder.function to call it with MySQL. I'm still not doing the numbering or replacement in the query, because i still think that's better done in code.
EntityManager em = emf.createEntityManager();
TypedQuery<Tuple> q = em.createQuery(criteria);
List<Tuple> booksAndSnippets = q.getResultList();
for (int i = 0; i < booksAndSnippets.size(); ++i) {
Tuple bookAndSnippet = booksAndSnippets.get(i);
int no = i + 1;
Book book = bookAndSnippet.get(root);
String snippet = bookAndSnippet.get(snippetExpr).replace("<br>", " ");
}
I really think you might have an easier time using JPQL, though!