collation in stored procedure - sql

I have a table which contains data in different languages. All fields are nvarchar(max).
I created a stored procedure which trim values of all the fields
Create Proc [dbo].[TrimValues]
as
update testdata
set city = dbo.trim(city),
state = dbo.trim(state),
country = dbo.trim(country),
schoolname = dbo.trim(schoolname)
after trim all non-english text become ?????

Either the parameter to your Trim user-defined function is declared as varchar instead of nvarchar or you are using a variable declared as varchar in that function to build the results or you have declared the results to be varchar instead of nvarchar. We'd need to see the source of the Trim function to know for sure.

Something wrong with your dbo.trim user-defined function then I'm guessing. Do you have the source for it?

make sure that you trim functions accepts nvarchar and not just varchar otherwise it will do an implicit conversion, can you post the code

Related

Does altering column type corrupt the column's existing data?

I am trying to change a column's datatype. The column of type VARCHAR has thousands of GUID values like look those shown below:
b1f4ff32-48d4-494e-a32c-044014cea9
bc5a1158-b310-49ff-a1f3-09d4f8707f69
4b7ebc9d-9fa1-42d9-811e-0b7b4b7297a
fc7ba848-98ea-4bc6-add7-11f0ee9c6917a21
485741ff-2ab2-4705-91b3-136389948b7c
I need to convert the column type to unqiqueidentifier using the script below. Can I do that safely without corrupting the column data?
alter table MyTable
alter column guidColumn uniqueidentifier not null
If you change the data type SQL Server will first check if all the values in the columns can be implicitly converted to the new data type; if they cannot then the ALTER will fail. If they can, then they will be implicitly converted and the ALTER will be successful (assuming no dependencies of course).
For a uniqueidentifier then either it's a valid value or it's not, so either the data will all convert or the ALTER won't take place. For something like a date and time data type, however, you could very easily end up with incorrect data if the data is stored in an ambiguous format like dd/MM/yyyy. This could mean a value like '12/05/2022' ends up being stored as the date value 2022-12-05 rather than 2022-05-12. For such scenarios you would therefore want to UPDATE the data to an unambiguous format first, and then ALTER the data type of the column.
The uniqueidentifier type is considered a character type for the purposes of conversion from a character expression, and therefore is subject to the truncation rules for converting to a character type.
Also there are limitations, uniqueidentifier type is limited to 36 char
So if you decide to truncate the table like in this example:
DECLARE #ID NVARCHAR(max) = N'0E984725-C51C-4BF4-9960-E1C80E27ABA0wrong';
SELECT #ID, CONVERT(uniqueidentifier, #ID) AS TruncatedValue;
This will be the result:
String
Truncated Value
0E984725-C51C-4BF4-9960-E1C80E27ABA0wrong
0E984725-C51C-4BF4-9960-E1C80E27ABA0
So, if your string is more or less than 36 it will not truncate correctly.
For more information check Microsoft documentation:
https://learn.microsoft.com/en-us/sql/t-sql/data-types/uniqueidentifier-transact-sql?view=sql-server-ver15

Trigger to convert empty string to 'null' before it posts in SQL Server decimal column

I've got a front table that essentially matches our SSMS database table t_myTable. Some columns I'm having problems with are those with numeric data types in the db. They are set to allow null, but from the front end when the user deletes the numeric value and tries to send a blank value, it's not posting to the database. I suspect because this value is sent back as an empty string "" which does not translate to the null allowable data type.
Is there a trigger I can create to convert these empty strings into null on insert and update to the database? Or, perhaps a trigger would already happen too late in the process and I need to handle this on the front end or API portion instead?
We'll call my table t_myTable and the column myNumericColumn.
I could also be wrong and perhaps this 'empty string' issue is not the source of my problem. But I suspect that it is.
As #DaleBurrell noted, the proper place to handle data validation is in the application layer. You can wrap each of the potentially problematic values in a NULLIF function, which will convert the value to a NULL if an empty string is passed to it.
The syntax would be along these lines:
SELECT
...
,NULLIF(ColumnName, '') AS ColumnName
select nullif(Column1, '') from tablename
SQL Server doesn't allow to convert an empty string to the numeric data type. Hence the trigger is useless in this case, even INSTEAD OF one: SQL Server will check the conversion before inserting.
SELECT CAST('' AS numeric(18,2)) -- Error converting data type varchar to numeric
CREATE TABLE tab1 (col1 numeric(18,2) NULL);
INSERT INTO tab1 (col1) VALUES(''); -- Error converting data type varchar to numeric
As you didn't mention this error, the client should pass something other than ''. The problem can be found with SQL Profiler: you need to run it and see what exact SQL statement is executing to insert data into the table.

How to pass multiply values parameter to a procedure

I want to pass multiply values parameter to my procedure and use it as a filter. My parameter is called #Month and it's datatype is NVARCHAR(MAX) in the procedure.
I have used filter as
WHERE (cal.CalendarYear = #Year) AND (cal.MonthId IN (#Month))
and also tried STRING_SPLIT function.
However, when I run my report, it return an error
Conversion failed when converting the nvarchar value '1,2,3,4,5,6,7,8,9,10,11,12' to data type int.
you cannot give a varchar string with comma separated values, and expect the query to process it as a 'in' list.
The way that would work is when you would concatenate your sql statement in the stored procedure, and then execute the sql string with sp_executesql.
Using string_split is one way of doing it, but you have to be aware that it gives you a table with varchars, not integers.
For completeness I should mention that the most 'robust' way of doing this is passing a table type variable to your stored procedure, as described here: How to pass table value parameters to stored procedure from .net code.
With the split_string, you could try something like this:
select
-- your fields
from
manytables mt
join string_split(#Month,',') months on cast(months.value as int) = cal.monthId
where
cal.Calenderyear = #year

Convert Binary Id Field to Text

I need the text (representation) of a id field in SQL Server 2005. Is there a way, we can generate the textual representation of the id field?
For instance, if the id field reads as 0x00000000000002F0, I need the text value of 0x00000000000002F0 so that I can run SUBSTR operations on the same.
Constraints
I am not allowed to create a stored procedure in the Database (as creation of SP is not allowed)
Thanks!
You can convert unicode strings to binary using
SELECT CONVERT(VARBINARY(40),N'Hello World')
(returns 0x480065006C006C006F00200057006F0072006C006400)
Convert from binary back to unicode using
SELECT CONVERT(NVARCHAR(20), 0x480065006C006C006F00200057006F0072006C006400)
(returns 'Hello World')
Whilst it's not immediately obvious to me why you would want to do this for comparison purposes (as opposed to matching binary values), the undocumented function sys.fn_varbintohexstr should do the trick
declare #vb binary(8)
,#vc varchar(20)
set #vb = 0x00000000000002F0
set #vc = sys.fn_varbintohexstr(#vb)
--prove that this works by concatenating a string to the varchar value
select #vb, '#' + #vc

TSQL - Case on Ntext (SQL 2005)

Stored Procedures in SQL 2005 - with field type NText
Im Writing a stored procedure to tidy up some data before importing it into Microsoft CRM.
So far all works fine.
However i need to do a case statement on a nText Field. It needs to check this field against about 3 or 4 text values and set a new field (already in the destination table) which is also an nText field.
However i am getting the error
"The data types ntext and varchar are incompatible in the equal to operator.
I have come across a few articles however their solutions all seem very complex.
Thanks for your help and advice in advanced.
I recommend, if at all possible, replacing the NTEXT type with NVARCHAR(MAX), since NTEXT is not a first class type and NVARCHAR is. This should be easy to do with an ALTER TABLE statement.
Most higher level code shouldn't care about the type change. Any procedural code that uses READTEXT, WRITETEXT, etc. to deal with the NTEXT columns can be simplified to just basic selects and updates.
If the type change is not possible you may have to wrap the comparisons and assignments with CAST() or CONVERT() operators, which is ugly.
NTEXT is deprecated in SQL Server 2005. You should use NVARCHAR(MAX) instead (NVARCHAR(MAX) can be used in CASE). Is it possible for you to change the type?
this works as well
CREATE TABLE #TEMP
(
MyDummy NTEXT
)
INSERT INTO #TEMP (MyDummy) Values ('test')
SELECT
CASE CAST(MyDummy AS NVARCHAR(MAX)) WHEN 'test' THEN 'ok' ELSE 'NOK' END MyTest
FROM #temp
drop table #temp