#{item().TableName} only gives first part of string - azure-data-factory

I have database from which I take nvarchar to lookup. Then I transport it to foreach. My problem is that when I use #item().TableName in dataset properties as value it works fine but when I use #{item().TableName} in query it takes only first part of it. So when it is "Receipt Header" I only get "Receipt"

Enclose the table name within the square brackets '[]' if it contains space or any special characters and use concat() function when combining constants with variables in the expression.
Query:
#concat('select MAX([Creation Date]) as NewWatermarkvalue from ',item().sourceSchema,'.[',item().TableName),']')

Related

Azure Data Factory - Dynamic Skip Lines Expression

I am attempting to import a CSV into ADF however the file header is not the first line of the file. It is dynamic therefore I need to match it based on the first column (e.g "TestID,") which is a string.
Example Data (Header is on Line 4)
Date:,01/05/2022
Time:,00:30:25
Test Temperature:,25C
TestID,StartTime,EndTime,Result
TID12345-01,00:45:30,00:47:12,Pass
TID12345-02,00:46:50,00:49:12,Fail
TID12345-03,00:48:20,00:52:17,Pass
TID12345-04,00:49:12,00:49:45,Pass
TID12345-05,00:50:22,00:51:55,Fail
I found this article which addresses this issue however I am struggling to rewrite the expression from using an integer to using a string.
https://kromerbigdata.com/2019/09/28/adf-dynamic-skip-lines-find-data-with-variable-headers
First Expression
iif(!isNull(toInteger(left(toString(byPosition(1)),1))),toInteger(rownum),toInteger(0))
As the article states, this expression looks at the first character of each row and if it is an integer it will return the row number (rownum)
How do I perform this action for a string (e.g "TestID,")
Many Thanks
Jonny
I think you want to consider first line that starts with string as your header and preceding lines that starts with numbers should not be considered as header. You can use isNan function to check if the first character is Not a number(i.e. string) as seen in the below modified expression:
iif(isNan(left(toString(byPosition(1)),1))
,toInteger(rownum)
,toInteger(0)
)
Following is a breakdown of the above expression:
left(toString(byPosition(1)),1): gets first character fron left side of the first column.
isNan: checks if the character is "not a number".
iif: not a number, true then return rownum, false then return 0.
Or you can also use functions like isInteger() to check if the first character is an integer or not and perform actions accordingly.
Later on as explained in the cited article you need to find minimum rownum to skip.
Hope it helps.

pg_get_serial_sequence in postgres fails and returns misleading error

This is not obviuos to me.
When I do:
SELECT MAX("SequenceNumber") FROM "TrackingEvent";
It returns perfectly fine with the correct result
When I do:
SELECT nextval(pg_get_serial_sequence("TrackingEvent", "SequenceNumber")) AS NextId
It returns an error which says
column "TrackingEvent" does not exist.
Not only is it wrong but the first argument of the function pg_get_serial_sequence takes a table name and not a column name, so the error is aslo misleading.
Anyways, can someone explain to me why I get an error on the pg_get_serial_sequence function ?
pg_get_serial_sequence() expects a string as its argument, not an identifier. String constants are written with single quotes in SQL, "TrackingEvent" is an identifier, 'TrackingEvent' is a string constant.
But because the function converts the string constant to an identifier, you need to include the double quotes as part of the string constant. This however only applies to the table name, not the column name, as explained in the manual
Because the first parameter is potentially a schema and table, it is not treated as a double-quoted identifier, meaning it is lower cased by default, while the second parameter, being just a column name, is treated as double-quoted and has its case preserved.
So you need to use:
SELECT nextval(pg_get_serial_sequence('"TrackingEvent"', 'SequenceNumber'))
This is another good example why using quoted identifiers is a bad idea. You should rename "TrackingEvent" to tracking_event and "SequenceNumber" to sequence_number

PostgreSQL regexp.replace all unwanted chars

I have registration codes in my PostgreSQL table which are written messy, like MU-321-AB, MU/321/AB, MU 321-AB and so forth...
I would need to clear all of this to get MU321AB.
For this I uses following expression:
SELECT DISTINCT regexp_replace(ccode, '([^A-Za-z0-9])', ''), ...
This expression work as expected in 'NET' but not in PostgreSQL where it 'clears' only first occurrence of unwanted character.
How would I modify regular expression which will replace all unwanted chars in string to get clear code with only letters and numbers?
Use the global flag, but without any capture groups:
SELECT DISTINCT regexp_replace(ccode, '[^A-Za-z0-9]', '', 'g'), ...
Note that the global flag is part of the standard regular expression parser, so .NET is not following the standard in this case. Also, since you do not want anything extracted from the string - you just want to replace some characters - you should not use capture groups ().

Using camelCased columns in a postgresql where clause

I have a table with camelCased column names (which I now deeply regret). If I use double quotation marks around the column names as part of the SELECT clause, they work fine, e.g. SELECT "myCamelCasedColumn" FROM the_table;. If, however, I try doing the same in the WHERE clause, then I get an error.
For example, SELECT * FROM the_table WHERE "myCamelCasedColumn" = "hello"; gives me the error column "hello" does not exist.
How can I get around this? If I don't surround the column in double quotation marks then it will just complain that column mycamelcasedcolumn does not exist.
In SQL string literals are enclosed in single quotes, not double quotes.
SELECT *
FROM the_table
WHERE "myCamelCasedColumn" = 'hello';
See the manual for details:
http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
The manual also explains why "myCamelCasedColumn" is something different in SQL than myCamelCasedColumn
In general you should stay away from quoted identifiers. They are much more trouble than they are worth it. If you never use double quotes everything is a lot easier.
The problem is you use double quote for strin literal "hello". Should be 'hello'. Double quotes is reserved for identifiers.

Escape character in JPQL

In JPQL what is escape character we can use to escape characters such as "'"?
Ex : I am doing something like
...where person.name='Andy'
Here it is working fine
but when the person's name is Andy's then the where clause becomes like
...where person.name='Andy's'
and it returns an error saying
It cannot figure out where string literal ends. Solution is nicely told in specification:
A string literal that includes a single quote is represented by two
single quotes—for example: ‘literal’’s’.
In your case means:
...where person.name='Andy''s'
Below is the sample code for executing query using named parameter.
Query query = entityManager.createQuery("SELECT p FROM Person p WHERE p.name LIKE :name" );
query.setParameter("name", personName);
Here, you can pass string to personName which may contain special character like "Andy's".
Also, it looks much clean & doesn't require to check parameter before query execution & altering the search string.