How to find and update columns containing a superscript character - sql

I'm using a SQL Server database. In a specific column, in some cells (which are of type varchar), there is this character : ³
I don't know how to find cells containing this character, and replace this character with character j.
When I use this query to find cells :
SELECT *
FROM table
WHERE col LIKE '%³%'
I get regular 3's as well.
Can you tell me how to do these? I looked up in the internet but I couldn't find what I want. Thanks.

All you need to do is:
UPDATE table
SET col = replace(col, N'³', 'j');
You don't need to search for the rows before updating / replacing the values, so no need for a SELECT. All you need to do is UPDATE.
If you want to add more conditions to filter your rows and only update some, you can just use a WHERE clause and specify more filters.
UPDATE table
SET col = replace(col, N'³', 'j');
WHERE col NOT LIKE '%..%'
AND col2 ...
AND col3 ...
etc.
You can use the same WHERE clause in a simple SELECT to see what rows will get updated before running the UPDATE.
In order not to go over all of the rows and to make your query faster, you can add a WHERE clause to update only the rows which contain that character.
EDIT/UPDATE (final):
In order to detect if data is uppercase / superscript you need to use collation:
UPDATE #t
SET col = replace(col, NCHAR(179) COLLATE SQL_Latin1_General_CP1_CS_AS, 'j');

This only works if you are using a case sensitive collation, use NCHAR(179) to represent the superscript:
create table #t (col1 nvarchar(50) COLLATE SQL_Latin1_General_CP1_CS_AS)
INSERT INTO #t
VALUES (NCHAR(179)),('3')
UPDATE #t
SET col1 = REPLACE(col1, NCHAR(179), 'j')
WHERE col1 like N'%' + NCHAR(179) + N'%'
SELECT *
FROM #t
**EDIT
As Radu has pointed out this will work without the table having case sensitive collation:
create table #t (col1 nvarchar(50))
INSERT INTO #t
VALUES (NCHAR(179)),('3')
UPDATE #t
SET col1 = REPLACE(col1, NCHAR(179) COLLATE SQL_Latin1_General_CP1_CS_AS, 'J')
WHERE col1 like N'%' + NCHAR(179) + N'%' COLLATE SQL_Latin1_General_CP1_CS_AS
SELECT *
FROM #t

Related

SQL Query Dynamically Create Multiple LIKE/OR Clause

I am trying to create the answer
SELECT *
FROM table
WHERE column LIKE 'Text%'
OR column LIKE 'Hello%'
OR column LIKE 'That%'
in below link:
Combining "LIKE" and "IN" for SQL Server
The problem is, in my example the values in the answer 'Text', 'Hello' and 'That' are not hard coded, they are populated from an application multi-select control and can be NULL value or a comma-separated string like this :
DECLARE #String_With_Commas nvarchar(255);
SET #String_With_Commas = N'Mercedes,BMW,Audi,Tesla,Land Rover';
I have tried below code, but it didn't work :
DECLARE #SearchString = CONCAT('''',REPLACE(#String_With_Commas, N',', N'%'' OR column LIKE '''));
And use it like :
WHERE column LIKE #SearchString + '%' + ''''
Assuming you are using a fully supported version of SQL Server, a couple ideas:
JOIN to STRING_SPLIT:
SELECT *
FROM dbo.YourTable YT
JOIN STRING_SPLIT(#YourVariable,',') SS ON YT.YourColumn LIKE SS.[value] + '%';
This will, however, return multiple rows if there can be multiple matches.
Use an EXISTS:
SELECT *
FROM dbo.YourTable YT
WHERE EXISTS (SELECT 1
FROM STRING_SPLIT(#YourVariable,',') SS
WHERE YT.YourColumn LIKE SS.[value] + '%');
This won't return the same row twice, if there are multiple matches.
From the comments on this answer, the requirement that the parameter be NULLable was omitted in the question. I would therefore suggest you use the EXISTS solution:
SELECT *
FROM dbo.YourTable YT
WHERE EXISTS (SELECT 1
FROM STRING_SPLIT(#YourVariable,',') SS
WHERE YT.YourColumn LIKE SS.[value] + '%')
OR #YourVariable IS NULL
OPTION (RECOMPILE);

SQL Server: Convert single row to comma delimited (separated) format

As the title states, I need help in converting a single row of data E.g,
col1 col2 col3 <-- This are column names
value1 value2 value3
To something like
dataResult <-- this is the column name from running the procedure or call
value1,value2,value3
The requirements are that this call ( or rather procedure) needs to be able to accept the results of sql queries of any column length and is able to convert that row to a comma delimited string format. Been stuck at this for weeks any help would be greatly appreciated...
EDIT*
Assume the unique key is the first column. Also assume that only 1 row will be returned with each query. Multiple rows will never occur.
The idea is to convert that row to a comma separated string without having to select the column names manually (in a sense automatically convert the query results)
You might try it like this:
A declared table variable to mock-up as test table. Be aware of the NULL value in col2!
DECLARE #tbl TABLE(col1 VARCHAR(100),col2 VARCHAR(100),col3 VARCHAR(100));
INSERT INTO #tbl VALUES('test1',NULL,'test3');
--This is the query:
SELECT
STUFF(
(
SELECT ',' + elmt.value('.','nvarchar(max)')
FROM
(
SELECT
(
/*YOUR QUERY HERE*/
SELECT TOP 1 *
FROM #tbl
/*--------------------*/
FOR XML AUTO ,ELEMENTS XSINIL,TYPE
)
) AS A(t)
CROSS APPLY t.nodes('/*/*') AS B(elmt)
FOR XML PATH('')
),1,1,'')
FOR XML AUTO will return each row as XML with all the values within attributes. But this would omit NULL values. Your returned string would not inlcude the full count of values in this case. Stating ELEMENT XSINIL forces the engine to include NULL values into the XML. This CROSS APPLY t.nodes('/*/*') will return all the elements as derived table and the rest is re-conactenation.
See the double comma in the middle! This is the NULL value of col2
test1,,test3
ATTENTION: You must be aware, that the whole approach will break, if there is a comma part of a (string) column...
Hint
Better was a solution with XML or JSON. Comma separated values are outdated...
Applay the next Approach:-
Use For Xml to sperate comma,
Get Columns Names Via using INFORMATION_SCHEMA.COLUMNS.
According to your need, select TOP (1) for getting First
Row.
Demo:-
Create database MyTestDB
go
Use MyTestDB
go
Create table Table1 ( col1 varchar(10), col2 varchar(10),col3 varchar(10))
go
insert into Table1 values ('Value1','Value2','Value3')
insert into Table1 values ('Value11','Value12','Value13')
insert into Table1 values ('Value21','Value22','Value23')
go
Declare #Values nVarchar(400),
#TableName nvarchar (100),
#Query nvarchar(max)
Set #TableName = 'Table1'
Select #Values = Stuff(
(
Select '+'','' + ' + C.COLUMN_NAME
From INFORMATION_SCHEMA.COLUMNS As C
Where C.TABLE_SCHEMA = T.TABLE_SCHEMA
And C.TABLE_NAME = T.TABLE_NAME
Order By C.ORDINAL_POSITION
For Xml Path('')
), 1, 2, '')
From INFORMATION_SCHEMA.TABLES As T
where TABLE_NAME = #TableName
select #Values = right(#Values,len(#Values)-4)
select #Query = 'select top(1)' + #Values + ' from ' + #TableName
exec sp_executeSQL #Query
Result:-

Replace Quotations in records SQL Server

I have records with quotations that I would like to replace with ''.
Example:
"ASKHELLO"SE --> ASKHELLO SE
""HELLO""1 --> HELLO 1
How can I do this in SQL Server?
I know replace function, but how do I get the pattern to check for to be any character other than "".
UPDATE
wordname
SET
wordname = REPLACE(deal, '"'+ '%', '')
This is incorrect. Help, please.
I am adding another answer based on your comment about double spaces on my original answer. ID in this case is arbitrary but I am huge fan of always having a primary key of some kind. XML we meet again!
--Setup the Table
DECLARE #T TABLE (wordname VARCHAR(25))
INSERT INTO #T VALUES ('"ASKHELLO"SE'),('""HELLO""1')
SELECT * FROM #T
--DECLARE AND SET XML REPLACING " with spaces
DECLARE #XML XML =
(
SELECT ROW_NUMBER() OVER (ORDER BY wordname ASC) AS "#ID",
CONVERT(XML,'<PART>' + REPLACE(CAST(CAST(REPLACE(wordname, '"',' ') AS VARCHAR(25)) AS VARCHAR(max)),' ',' </PART><PART>') + '</PART>') AS Word
FROM #T AS T
FOR XML PATH('Node'), ROOT('Nodes'), ELEMENTS, TYPE
)
SELECT #XML
--SHRED THE XML (WHICH WILL REMOVE NULLS) AND TRIM
;WITH
SHRED AS
(
SELECT ID = FieldAlias.value('(#ID)[1]','INT'),
WordName = FieldAlias.value('(Word)[1]','varchar(max)')
FROM #XML.nodes('/Nodes/Node') AS TableAlias(FieldAlias)
)
SELECT S.ID,
LTRIM(RTRIM(S.WordName)) AS WordName
FROM Shred AS S
And it should be relatively trivial for you to update off the shredded result set at this point, but let me know if you need that too. Replace the #T with your original table to pull off your data set.
REPLACE function does a global replace within a string. So u can do simple
UPDATE
wordname
SET
deal = REPLACE(deal, '"', '')
Assuming that "wordname" is your table and "deal" is a field you're replacing.
This will simple remove the double quotes. If you need to replace it with space use ' ' instead of ''
Does this help you? Try using LTRIM to strip off leading spaces after the replace. Here's a quick example based on your code:
DECLARE #T TABLE (wordname VARCHAR(25))
INSERT INTO #T VALUES ('"ASKHELLO"SE'),('""HELLO""1')
SELECT * FROM #T
SELECT LTRIM(REPLACE(wordname, '"',' '))
FROM #T

SQL - Select Uppercase fields

i have a table, that has a column (SQL_Latin1_General_CP1_CI_AI), and has a couple of hundred rows where that column is filled in all uppercase.
I would like to know if it is possible to select all the rows that have that field in uppercase and, ultimately if i can make an update to capitalize the fields.
I'm using SQL Management Studio on MSSQL 2005
Thanks
DECLARE #T TABLE
(
col VARCHAR(3) COLLATE SQL_Latin1_General_CP1_CI_AI
)
INSERT INTO #T
SELECT 'foo' UNION ALL SELECT 'BAR' UNION ALL SELECT ''
UPDATE #T
SET col = STUFF(LOWER(col),1,1,LEFT(col,1))
WHERE col = UPPER(col) COLLATE SQL_Latin1_General_CP1_CS_AS AND LEN(col) >1
SELECT * FROM #T
Returns
(1 row(s) affected)
col
----
foo
Bar
(3 row(s) affected)

Write a T-SQL query that filters records containing NCHAR(2028)

My ultimate goal is to write a sql script that selects data from a particular table where a nvarchar(max) column contains the character NCHAR(2028).
But the obvious:
select *
from tablename
where columnname like '%' + NCHAR(2028) + '%'
returns all rows.
Use a binary collation for your like comparison.
select *
from tablename
where columnname COLLATE Latin1_General_Bin like '%' + NCHAR(2028) + '%'
This works
CREATE TABLE #temp (columnname NVARCHAR(128))
INSERT #temp VALUES ('a')
INSERT #temp VALUES ( NCHAR(2028))
INSERT #temp VALUES ('b')
INSERT #temp VALUES ('c' + NCHAR(2028) + 'c')
INSERT #temp VALUES ('a' + NCHAR(2028) + 'b')
SELECT *
FROM #temp
WHERE ColumnName COLLATE Latin1_General_Bin Like N'%' + NCHAR(2028) + '%'
drop table #temp
I think you're hitting limitations on characters that are outside of your collation. I had some weird behavior. Notice the result of the two SELECTs here:
CREATE TABLE dbo.foo
(
id INT IDENTITY(1,1),
bar NVARCHAR(128)
);
INSERT dbo.foo(bar) SELECT N'foobar'
UNION
SELECT N'foo' + NCHAR(2028) + N'bar'
SELECT *
FROM dbo.foo
WHERE bar LIKE N'%' + NCHAR(2028) + '%';
TRUNCATE TABLE dbo.foo;
INSERT dbo.foo(bar)
SELECT N'foo' + NCHAR(2028) + N'bar'
SELECT *
FROM dbo.foo
WHERE bar LIKE N'%' + NCHAR(2028) + '%';
DROP TABLE dbo.foo;
Notice that whether we've inserted one row or two, we always get the first row back, even though the query is the same and the data has changed.
Unfortunately pasting the actual value of NCHAR(2028) into SSMS doesn't work because it is not in the set of supported characters (I get a glyph like a question mark box in Super Mario Brothers). Otherwise I would just suggest:
WHERE columnname LIKE N'%߬%';
If you can do that from your code (and not worry about SSMS), it may be a workable alternative.