LIKE does not support collation: en-ci-rtrim - snowflake-cloud-data-platform

Trying to do a simple Snowflake query as such:
SELECT *
FROM TABLE
WHERE NAME_COLUMN LIKE '%ABC%'
Yet I'm getting the following error.
SQL compilation error: error line 17 at position 12 Function LIKE does not support collation: en-ci-rtrim.
What is the work around here? I don't have the ability to alter the underlying table or the collation attributes.

You can re-colate in real time:
create or replace temp table collation_demo (
uncollated_phrase varchar,
stack_phrase varchar collate 'en-ci-rtrim'
);
insert into collation_demo (uncollated_phrase, stack_phrase)
values ('pinata', 'pirata');
select *
from collation_demo
where collate(stack_phrase, 'en') like '%pi%'
order by stack_phrase
If you remove the collate() call around stack_phrase you'll get the same error. But with it, the query works as expected.
Another workaround is to use a different string comparing function that supports the existing collation. For example, contains():
select *
from collation_demo
where contains(stack_phrase, 'PI');
Works!

Related

SQL Server: Error converting data type varchar to numeric (Strange Behaviour)

I'm working on a legacy system using SQL Server in 2000 compatibility mode. There's a stored procedure that selects from a query into a virtual table.
When I run the query, I get the following error:
Error converting data type varchar to numeric
which initially tells me that something stringy is trying to make its way into a numeric column.
To debug, I created the virtual table as a physical table and started eliminating each column.
The culprit column is called accnum (which stores a bank account number, which has a source data type of varchar(21)), which I'm trying to insert into a numeric(16,0) column, which obviously could cause issues.
So I made the accnum column varchar(21) as well in the physical table I created and it imports 100%. I also added an additional column called accnum2 and made it numeric(16,0).
After the data is imported, I proceeded to update accnum2 to the value of accnum. Lo and behold, it updates without an error, yet it wouldn't work with an insert into...select query.
I have to work with the data types provided. Any ideas how I can get around this?
Can you try to use conversion in your insert statement like this:
SELECT [accnum] = CASE ISNUMERIC(accnum)
WHEN 0 THEN NULL
ELSE CAST(accnum AS NUMERIC(16, 0))
END

SQL Query with Collation Issues

I am trying to compare data results from views on a test instance and on a live instance. Both instances are on the same server.
I have created a link between them both so I can query between them, but I am receiving a collation error - Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Latin1_General_CI_AI" in the EXCEPT operation.
I am trying to use this query to compare results because they should be the same results from both instances:
SELECT * FROM (SELECT * FROM
INSTANCE1.dbo.View1) as TEST
EXCEPT
SELECT * FROM (SELECT * FROM
[SERVER\INSTANCE2].Database.dbo.View1) as LIVE
I have tried to wrap the query in CTE, and have also been trying to specify default collation but everything I try doesn't work.
Is there a way I can query these two views on seperate instances to compare the results without creating a temp table and by getting SQL to ignore the conflict?
Thank you so much, I appreciate any help.
Well the error message tells you exactly what the problem is, but not which column or columns it belongs to, and because you use select * I have no idea what the columns names are either. You will need to identify columns in those tables that store strings, and then force then to use the same collation, something like this I think (untested):
SELECT stringcol
FROM (
SELECT stringcol collate SQL_Latin1_General_CP1_CI_AS
FROM INSTANCE1.dbo.View1) as TEST
EXCEPT
SELECT stringcol
FROM (SELECT stringcol collate SQL_Latin1_General_CP1_CI_AS
FROM [SERVER\INSTANCE2].Database.dbo.View1
) as LIVE
So you will need to specify the columns, and you will need to also specify the collation to be used for string columns.

Unable to run "INSERT INTO" from Azure SQL external table

In my Azure SQL DB I have an external table - let's call this tableName_origData - and I have another table which we'll refer to as tableName.
tableName was created using a generated CREATE script from tableName_origData (in its original location) so I can be sure that all the column types are identical.
However, when I run
INSERT INTO tableName (
[list of column names]
)
SELECT
[same list of column names]
FROM
tableName_origData
I encounter the following exception:
Large object column support is limited to only nvarchar(max) data
type.
As far as my understanding of Azure SQL's data types goes, I don't have anything larger than NVARCHAR(MAX). Furthermore, the message implies that NVARCHAR(MAX) is supported (and I can see that the same script works on other tables which contain NVARCHAR(MAX).
Can anyone better explain the cause of this exception and what I might need to do in order to insert its data into an identical table?
Here is a list of all the column types used in the table(s):
BIGINT x 3
NCHAR(20) x 1
NVARCHAR(45) x 5
NVARCHAR(100) x 14
NVARCHAR(MAX) x 10
External tables is read-only. The developer can select data, but cannot perform any form of DML-processing
To solve this issue please use this technique:
https://technology.amis.nl/2005/04/05/updateable-external-tables/
Warn: Unless for the simplest of uses, we do not recommend using this technique for any serious application

Create SQL user-defined function in ColdFusion with MS SQL Server

I'm doing queries in which I want to extract the left-most n characters from a string that has been stripped of all leading and following spaces. An example is:
Select SUBSTRING(LTRIM(RTRIM(somefield)), 0, #n) AS mydata
FROM sometable
It's the only way I can figure to do it on a SQL Server.
I've never written a UDF before, but I think if I was just working on a SQL Server, I could create a user-defined function such as:
CREATE FUNCTION udfLeftTrimmed
(
#inputString nvarchar(50),
#n int
)
RETURNS nvarchar(#n)
AS
BEGIN
RETURN SUBSTRING(LTRIM(RTRIM(#inputString)), 0, #n);
END
I could then do something like:
Select udfLeftTrimmed(somefield,6) AS mydata
FROM sometable
which is at least a little easier to read and understand.
The question is, how do I create the UDF in ColdFusion? All my searches for SQL user-defined function in ColdFusion just gave me how to create ColdFusion functions.
Since there is nothing special or "dynamic" about your UDF you really don't need to create it in CF. You should just create it using MSSQL Manager. UDFs in SQL are like stored procedures. Once created they are a part of the DB/Schema. so create once, use as many times as you like (as #leigh has mentioned).
Keep in mind that using a SQL udf in SQL usually requires the user prepend as in:
<cfquery...>
Select dbo.udfLeftTrimmed(somefield,6) AS mydata
FROM sometable
</cfquery>
Note the "dbo.udf..." that dbo is important and may be why your subsequent try is failing - besides getting a duplicate UDF error by now. :)
NOTE:
To follow up on your comments and Leighs, you can create your UDF in a DB accessible to your user then access it as dbo.dbname.function ... as inthe following code:
<cfquery...>
Select dbo.myspecialDatabase.udfLeftTrimmed(somefield,6) AS mydata
FROM sometable
</cfquery>
Then you need only create it one time.

My ContainsTable query is not working - please help :)

I've got a full text catalogue setup. It has a unique key count of 117 with 19 items. The table has 19 rows only.
The table has an NVARCHAR(50) field called ClientGuid. It's a guid with some weird text at the end.
eg..
8b6ef4a504dd1a57f079180e7f6eb4a0(-)
8b6ef4a504dd1a57f079180e7f6eb4a0(OK)
(and no, i didn't defined that text field data - we're sourcing it from a 3rd party API.
anways, this is my sql and the query i run against it. When i run the query, i get ZERO results back :(
ALTER FUNCTION [dbo].[Foo_HiJonSkeet]
(
#ClientGuid NVARCHAR(50)
)
RETURNS TABLE
AS
RETURN
(
SELECT KEY_TBL.[Key] as LogEntryId,
KEY_TBL.RANK as Relevance
FROM CONTAINSTABLE(LogEntries, ClientGuid, #ClientGuid) AS KEY_TBL
)
SELECT * FROM Foo_HiJonSkeet('8b')
Any suggestions?
Server is Sql Server 2008.
You can try the following construction:
SELECT * FROM Foo_HiJonSkeet('"8b*"')
adding the double quotes and an asterisk after the original search term. It should work.
But in the case if all the searches will be similar to the example you've posted above, I advise you to use LIKE statement instead of using full text search.

Resources