How can I use tSQL to find a string, and if it exists, return everything before that string?
i.e. in the example below, in an ETL process, how would we take the column from source, identify the string ?uniquecode= and therefore remove that, and everything else after it, in the SELECT statement for the sink column?
How can I best modify this tSQL statement below to return the values in SinkPageURL column above?
SELECT SourcePageURL FROM ExampleTable
I have attempted a Fiddle here - http://sqlfiddle.com/#!18/3b60a/4 using the below statement. It is disregarding the values where '?uniquecode=' does not exist though, and also leaves the '?' symbol. Need this to work with MS SQL Server '17.
Somewhat close, but no cigar. Help appreciated!
SELECT LEFT(SourcePageURL, CHARINDEX('?uniquecode=', SourcePageURL)) FROM sql_test
Try this query:
SELECT
CASE WHEN CHARINDEX('?uniquecode=', SourcePageURL) > 0
THEN SUBSTRING(SourcePageURL,
1,
CHARINDEX('?uniquecode=', SourcePageURL) - 1)
ELSE SourcePageURL END AS new_source
FROM sql_test;
If you instead wanted to update the source URLs in your example using this logic, you could try the following:
UPDATE sql_test
SET SourcePageURL = SUBSTRING(SourcePageURL,
1,
CHARINDEX('?uniquecode=', SourcePageURL) - 1)
WHERE SourcePageURL LIKE '%?uniquecode=%';
Related
I'm trying to parameterize my postgresql query in order to prevent SQL injection in my ruby on rails application. The SQL query will sum a different value in my table depending on the input.
Here is a simplified version of my function:
def self.calculate_value(value)
calculated_value = ""
if value == "quantity"
calculated_value = "COALESCE(sum(amount), 0)"
elsif value == "retail"
calculated_value = "COALESCE(sum(amount * price), 0)"
elsif value == "wholesale"
calculated_value = "COALESCE(sum(amount * cost), 0)"
end
query = <<-SQL
select CAST(? AS DOUBLE PRECISION) as ? from table1
SQL
return Table1.find_by_sql([query, calculated_value, value])
end
If I call calculate_value("retail"), it will execute the query like this:
select location, CAST('COALESCE(sum(amount * price), 0)' AS DOUBLE PRECISION) as 'retail' from table1 group by location
This results in an error. I want it to execute without the quotes like this:
select location, CAST(COALESCE(sum(amount * price), 0) AS DOUBLE PRECISION) as retail from table1 group by location
I understand that the addition of quotations is what prevents the sql injection but how would I prevent it in this case? What is the best way to handle this scenario?
NOTE: This is a simplified version of the queries I'll be writing and I'll want to use find_by_sql.
Prepared statement can not change query structure: table or column names, order by clause, function names and so on. Only literals can be changed this way.
Where is SQL injection? You are not going to put a user-defined value in the query text. Instead, you check the given value against the allowed list and use only your own written parts of SQL. In this case, there is no danger of SQL injection.
I also want to link to this article. It is safe to create a query text dynamically if you control all parts of that query. And it's much better for RDBMS than some smart logic in query.
How can I use tSQL to find one of two strings, and if they exist, return everything before found string?
In an ETL process, how would we take the column from source, identify the strings ?uniquecode= OR /uniquecode= and therefore remove those, and everything else after them, in the SELECT statement for the sink column? i.e. matching desired outcome below.
On this SO question I was provided with a solution that finds ?uniquecode= successfully. I just need to find a way to modify it to also look for /uniquecode=
SELECT
CASE WHEN CHARINDEX('?uniquecode=', SourcePageURL) > 0
THEN SUBSTRING(SourcePageURL,
1,
CHARINDEX('?uniquecode=', SourcePageURL) - 1)
ELSE SourcePageURL END AS new_source
FROM sql_test;
You may modify your current query as follows:
SELECT
CASE WHEN SourcePageURL LIKE '%?uniquecode=%'
THEN SUBSTRING(SourcePageURL,
1,
CHARINDEX('?uniquecode=', SourcePageURL) - 1)
WHEN SourcePageURL LIKE '%/uniquecode%'
THEN SUBSTRING(SourcePageURL,
1,
CHARINDEX('uniquecode=', SourcePageURL) - 1)
ELSE SourcePageURL END AS new_source
FROM sql_test;
Demo
In SQL Server Compact, I'm trying to remove a trailing comma that came from a goof which affected several thousand rows of a NVARCHAR column.
UPDATE myTable
SET col = LEFT(col, LEN(col)-1)
WHERE col LIKE '%,';
throws the error:
There was an error parsing the query. [ Token in error = LEFT ]
Can SQL Server CE not parse that query? Or, can someone offer another approach?
Note: I tried this in CompactView, I'm not sure if that's the problem.
Based off this example I was able to get it done using SUBSTRING:
UPDATE myTable
SET col = SUBSTRING(col, 0, LEN(col))
WHERE col LIKE '%,';
The proposed solution with using SET col = SUBSTRING(col, 0, LEN(col)) is a bit unclear.
This is working as a side effect of the SUBSTRING second parameter starting_position being "1 based". So 0 in this case is kind of negative (you could also use i.e. -3 and 4 characters would be stripped then instead of 1).
IMHO it would be much more clear to use this:
UPDATE myTable
SET col = SUBSTRING(col, 1, LEN(col)-1)
WHERE col LIKE '%,';
Which shows the code's intent
UPDATE myTable
SET col = SUBSTR(col, 0, (LENGTH(col) - 1))
WHERE col LIKE '%,';
I want a query which will return a combination of characters and number
Example:
Table name - emp
Columns required - fname,lname,code
If fname=abc and lname=pqr and the row is very first of the table then result should be code = ap001.
For next row it should be like this:
Fname = efg, lname = rst
Code = er002 and likewise.
I know that we can use substr to retrieve first letter of a colume but I don't know how to use it to do with two columns and how to concatenate.
OK. You know you can use substr function. Now, to concatenate you will need a concatenation operator ||. To get the number of row retrieved by your query, you need the rownum pseudocolumn. Perhaps you will also need to use to_char function to format the number. About all those functions and operators you can read in SQL reference. Anyway I think you need something like this (I didn't check it):
select substr(fname, 1, 1) || substr(lname, 1, 1) || to_char(rownum, 'fm009') code
from emp
I am trying to execute a native query and pass run-time parameters and get the result as a List. When I try to process the Object [], one of the columns fetched is a String. But it comes out as java.lang.Character instead of String. Here is the query below:
SELECT CASE
WHEN (TRUNC(abm.credit_card_expiration_date) BETWEEN trunc(SYSDATE) AND
trunc(last_day(SYSDATE))) THEN
'Expires'
ELSE
'Expired'
END EXP_STATUS,
TO_CHAR(abm.credit_card_expiration_date, 'MM/YY') EXP_DATE
FROM account_billing_methods abm
WHERE abm.account_id = 201103
AND abm.billing_type_id = 1
AND TRUNC(abm.credit_card_expiration_date) <= TRUNC(LAST_DAY(SYSDATE))
The EXP_STATUS column could not be typecasted into String as it is of type Character. Any ideas of why it does not work?
Regards,
-Anand
I had the same problem and changed the select clause of my query to:
EXP_STATUS || '' as EXP_STATUS
Then it is a VARCHAR instead of a CHAR and JPA will return it as a String instead of a Character.
If someone knows a better/more elegant solution, I would appreciate if you could share it.