Redshift regexp_replace - amazon-redshift

I have a string like:
'start the string {replace this} continue the string {replace this too} and for good measure, continue the string some more'
I need the result to be:
'start the string % continue the string % and for good measure, continue the string some more'
I am trying to replace any/all occurrence(s) of open/close squiggly brackets with % to use in a dynamic SQL statement utilizing the like operator.

To replace the {replace this} like strings with % you can use a regex replace function like this:
with input(txt) as (
select 'start the string {replace this} continue the string {replace this too} and for good measure, continue the string some more'::varchar
)
select regexp_replace(txt, '\\{[\\w\\s]*\\}', '%') from input;
returns
start the string % continue the string % and for good measure, continue the string some more
But instead of having the described 2 step search where you first replace all template parts with % and then do the LIKE over that, why not just do a regex search?
with input(txt) as (
select 'start the string {replace this} continue the string {replace this too} and for good measure, continue the string some more'::varchar
)
select txt from input
where
txt ~ 'start the string \\{.*\\} continue the string \\{.*\\} and for good measure, continue the string some more'

Related

PostgreSQL: using strings in SQL subquery text in a function

I'm using the pgr_drivingDistance function that requires a SQL subquery as text like so:
pgr_drivingDistance(
'SELECT id, source, target, cost, reverse_cost FROM edges', start_vid, dist, true
)
I would like to subset the edges in the edges table with a where clause like so:
pgr_drivingDistance(
'SELECT id, source, target, cost, reverse_cost FROM edges WHERE col = 'some_string'', start_vid, dist, true
)
The problem is I cannot use single quotes in this case for the string. I tried to escape the quotes of the string with ''', backslash, $$ notations without success.
Is there a way to do this?
There's various ways to escape single quotes (apostrophes) in Postgres string literals:
"To include a single-quote character within a string constant, write two adjacent single quotes"
pgr_drivingDistance('SELECT … WHERE col = ''some_string'' ', start_vid, dist, true)
"A single quote can be included in an escape string by writing \', in addition to the normal way of ''."
pgr_drivingDistance(e'SELECT … WHERE col = \'some_string\' ', start_vid, dist, true)
"Inside the dollar-quoted string, single quotes can be used without needing to be escaped"
pgr_drivingDistance($$SELECT … WHERE col = 'some_string'$$, start_vid, dist, true)

REGEXP_REPLACE replace spaces between two symbols

I need to replace all spaces with one % between two specific symbols (# and &); like followings:
'this # is test &that did not #turn& out well'
should be converted to
'this #%is%test%&that did not #turn& out well'
and
'#pattern matching& is my number one enemy'
to
'#pattern%matching& is my number one enemy'
I almost read all related questions in stackoverflow and other sites but couldn't get a helpful answer.
One (inefficient) way of doing this is by doing multiple REGEXP_REPLACE calls.
For example, lets look at the following plpgsql function.
CREATE OR REPLACE FUNCTION replaceSpacesBetweenTwoSymbols(startChar TEXT, endChar TEXT, textToParse TEXT)
RETURNS TEXT
AS $$
DECLARE resultText TEXT := textToParse;
DECLARE tempText TEXT := textToParse;
BEGIN
WHILE TRUE LOOP
tempText = REGEXP_REPLACE(resultText,
'(' || startChar || '[^' || endChar || ']*)' || '( )(.*' || endChar || ')',
'\1%\3');
IF tempText = resultText
THEN RETURN resultText;
END IF;
resultText := tempText;
END LOOP;
RETURN resultText;
END;
$$
LANGUAGE 'plpgsql';
We create a function that takes three arguments, the startChar, the endChar and the textToParse which holds the text that will be trimmed.
We start by creating a a regular expression based on the startChar and endChar. If the value of startChar is # and the value of endChar is & we will get the following regular expression:
(#[^&]*)( )(.*&)
This regular expression is consisted of three groups:
(#[^&]*) - This group matches the text that is between the # and an an empty space character - ' ';
( ) - This group matches a single space character.
(.*&) - This group matches the text that is between a space character and the & character.
In order to replace the space (group 2), we use the following REGEXP_REPLACE call:
REGEXP_REPLACE(resultText,' (#[^&]*)( )(.*&)', '\1%\3')
From that expression you can see that we are replacing the second group (which is a space) with the % character.
This way, we will only replace one space per one REGEXP_REPLACE execution.
Once we find that there are no more spaces that need to be replaced, we return the modified TEXT.
At this moment, the spaces are replaced with % characters. One last thing we need to do is to replace the multiple consecutive % characters with a single %.
That can be done with another REGEXP_REPLACE call at the end.
So for example:
SELECT REGEXP_REPLACE(replaceSpacesBetweenTwoSymbols('#','&','this # is test &that did not #turn& out well'),'%{2,}','%');
Will return
this #%is%test%&that did not #turn& out well
as a result, while this
SELECT REGEXP_REPLACE(replaceSpacesBetweenTwoSymbols('#','&','this is #a more complex& task #test a a & w'),'%{2,}','%');
will return
this is #a%more%complex& task #test%a%a%& w
as a result.

Ms Access Form - How to completely filter text using search button

`Option Compare Database
Option Explicit
Dim argcount As Integer
Dim mysql As String, msg As String, mysource As String, mycriteria As String, mysource1 As String, mysql1 As String
Private Sub AddtoWhere(FieldValue As Variant, FieldName As String, mycriteria As String, argcount As Integer)
' Create criteria for WHERE clause.
If FieldValue <> "" Then
' Add "and" if other criterion exists.
If argcount > 0 Then
mycriteria = mycriteria & " and "
End If
' Append criterion to existing criteria.
' Enclose FieldValue and asterisk in quotation marks.
mycriteria = (mycriteria & FieldName & " Like " & Chr(34) & FieldValue & Chr(42) & Chr(34))
' Increase argument count.
argcount = argcount + 1
End If
End Sub
Private Sub Search_Click()
Dim Search As String
here:
argcount = 0
' Initialize SELECT statement.
mysql = "SELECT * FROM tbltab WHERE "
mycriteria = ""
mysql1 = "SELECT * FROM tblTemp WHERE "
mycriteria = ""
' Use values entered in text boxes in form header to create criteria for WHERE clause.
AddtoWhere cboProduct, "ABC1", mycriteria, argcount
AddtoWhere cboSource, "ABC2", mycriteria, argcount
AddtoWhere cboPType, "ABC3", mycriteria, argcount
'If no criterion specifed, stop the search.
'you'll be glad you did if there are thousands of Persons maybe.
If mycriteria = "" Then
mycriteria = True
End If
' Create SELECT statement.
mysource = mysql & mycriteria
mysource1 = mysql1 & mycriteria
Dim strval As String
'set the recordsource of the subform to the resultset
Me!sfrmCap.Form.RecordSource = mysource
Me!sfrmCapTemp.Form.RecordSource = mysource1
Exit_cmdsearch_Click:
Exit Sub
Err_cmdsearch_Click:
DoCmd.Hourglass False
DoCmd.Echo True
MsgBox Err.Description & " Person Search Command Cancelled", vbInformation, "Person Search Command Cancelled"
Resume Exit_cmdsearch_Click
End Sub
`I have a form in which there are 2 subform. I have a search button which when click search record using combo box values but in one combo box it display just related record not the complete search.
Can anyone help me in this.
Thank you.
In AddtoWhere() you assemble your WHERE clause, adding new conditions like this:
mycriteria = (mycriteria & FieldName & " Like " & Chr(34) & FieldValue & Chr(42) & Chr(34))
If you are unsure about what this actually does, you can put a breakpoint on the line (double clicking in the margin in front of the line) and see for yourself while executing the program.
If you do, you'll find out that a new condition like this will be added:
Source Like "Pre 2017 Source1*"
The * (encoded with Chr(42) in your code) acts as a joker matching any characters, so this condition returns everything that begins with Pre 2017 Source1 - as you can see in the search results.
If you do not want this behaviour, just remove the star from the SQL code and only exact matches will be returned.
Btw.: You should improve that code line like this:
mycriteria = mycriteria & FieldName & " LIKE '" & Replace(FieldValue, "'", "''") & "'"
This removes the unnecessary use of Chr(), replaces double quotes by single quotes as SQL string delimiters as it is recommended, and enables the code to handle values that contain quotes, which would otherwise result in a runtime error.

How to ignore escape character ?

this is my string
$mystring = "INSERT INTO `glpi_networkports` (`entities_id`,`is_recursive`,`items_id`,`itemtype`,`comment`,`logical_number`,`name`,`networkinterfaces_id`,`ip`,`mac`,`netmask`,`gateway`,`subnet`,`netpoints_id`)"
How can i ignore escape ?
Because it gave me string like this :
INSERT INTO glpi_networkports (entities_id,is_recursive,items_id,itemtype,comment,logical_number,
ame,
etworkinterfaces_id,ip,mac,
etmask,gateway,subnet,
etpoints_id)
Thanks
Currently your select statement is changed because you used a double quoted string and `n is expanded to a new line, turning the select to an invalid statement.
Use single quotes to maintain the backticks and disable string expansion.
use quote or double the escape char:
$mystring = "INSERT INTO 'glpi_networkports' ..."
$mystring = "INSERT INTO ``glpi_networkports`` ...

replace string with split_part function

I want to replace the first word before delimeter ' ,' with ' 0, the first word ')
select replace('tab,graph,map', split_part('tab,graph', ',', 1) like 'tab','0, tab')
ERROR: function replace(unknown, boolean, unknown) does not exist
LINE 1: select replace('tab,graph,map', split_part('tab,graph', ',',...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
The replace function replaces all occurrences of the string so you have to make sure the string to replace is unique or use something else. However, regexp_replace only replaces the first occurrence by default so you can use that; your question is a little unclear about what the expected output is but maybe this is is what you're looking for:
=> select regexp_replace('tab,graph,map', ',', '0,');
regexp_replace
----------------
tab0,graph,map
Or this one:
=> select regexp_replace('tab,graph,map', 'tab,', '0,');
regexp_replace
----------------
0,graph,map
Or maybe even this:
=> select regexp_replace('tab,graph,map', 'tab,', '0,,');
regexp_replace
----------------
0,,graph,map
you need to cast, since the function expects replace(text, text, text) and does not know how to handle your literal strings calling them unknown...
cast('tab,graph,map' AS text)
also the 2nd param is a LIKE comparison ? which returns boolean, but the function replace expects it to be the delimiter.
CAST(split_part('tab,graph', ',', 1) AS text)
finally the last param (same problem as the first)
cast('0, tab' AS text)
of course if you really just want to prepend '0, ' to your string, 'tab,graph,map' you could just do that...
SELECT '0, ' || 'tab,graph,map' ;