Is it possible to save a multiline varchar in SQL Server?
DECLARE #SQL VARCHAR(256)
SELECT #SQL = 'SELECT
ID, Name
FROM
Cust'
INSERT INTO
MultiLineTBL (SQL)
VALUES
(#SQL)
So this query:
SELECT SQL From MultiLineTBL
will return:
SELECT
ID, Name
FROM
Cust
Not the straight line:
SELECT ID, NAME FROM Cust
How is it possible to store a multiline varchar?
Your sql query have syntex error:
DECLARE #SQL VARCHAR(256) ;
--please update query like that
set #SQL = 'insert into MultiLineTBL(col1,col2)
SELECT ID, Name FROM Cust';
--and execure like that:
exec(#SQL);
Yes, it is possible to store a multi-line varchar in a table. In fact, the value in your example is stored correctly.
As AlexK has correctly commented, multi-line values are not displayed correctly in SQL Server Management Studio when it is configured to return the results in a grid, and that (viewing the results in a grid) must be what gave you the wrong impression. As per my observation, SSMS replaces every control character, including CR (CHAR(13)) and LF (CHAR(10)), with a space in this display mode.
Try switching to Results to Text (Ctrl+T) before running the query and you will see that line delimiters are actually preserved.
Related
I have this type of data in a column in my table,,,
QCIM1J77477, 4650125572, QCCR1J77891, 4650312729, QCCR1J74974 --- remove without comma
or
QCIM1E107498,QCIM1E109835,4650092399/ QCCR1E91190, -- remove 4650092399
I want only that string which starts from QC,remove apart from QC,
so please tell me how can I achive it?
Beneath a piece of t-sql script that creates a temporary table #t with temporary variables. Here the temporary table exists untill you break your session, temporary variables exist during the execution of the script. I have a drop table statement at the bottom. Figure out yourself what you want with the table data and whether you want the data put in somewhere else, for example in a not-temporary table :).
I assume you want all the pieces of the string that contain 'QC' as seperate values. If you want your data back as it was originally, that is multiple strings per one column, then you could also do a group by trick. Then you do need a unique identifier of some sort, like name, id, guid of each row or identity.
create table #t ([QCs] nvarchar(100))
declare #str nvarchar(500)
set #str = 'QCIM1E107498,QCIM1E109835,4650092399/ QCCR1E91190'
--replace the above temporary variable with the column you are selecting
declare #sql nvarchar(4000)
select #sql = 'insert into #t select '''+ replace(#str,',',''' union all select ''') + ''''
print #sql
exec ( #sql )
select
QCs
,PATINDEX('%QC%',QCs) as StartPosition
,SUBSTRING(QCs,PATINDEX('%QC%',QCs),12) as QCsNew
from #t where QCs like '%QC%'
drop table #t
With PATINDEX you find the position where in the string 'QC' starts, and with SUBSTRING you tell the dbms to give back (here) 12 characters starting from the found StartPosition.
Beneath what the result looks like. QCsNew is your desired result.
QCs StartPosition QCsNew
QCIM1E107498 1 QCIM1E107498
QCIM1E109835 1 QCIM1E109835
4650092399/ QCCR1E91190 13 QCCR1E91190
I inherited some partially complete sql code that I can't get to work.
it accesses multiple databases, so it first searches for proper database using a userID number, then inserts that database name into a query. the part i'm having a problem with (extremely abbreviated) is...
DECLARE #sql AS VARCHAR(8000)
SET #sql = 'INSERT INTO ['+#DatabaseName+'].dbo.[customer]
( -- containing about 200 columns. )
VALUES(...)'
PRINT #sql
EXEC(#sql)
i would get errors in the middle of a column name, sometimes saying it's expecting a parenthesis or quote. i started deleting white space so that, ie, [first name],[last name] were on the same line and not two different lines and that would get me a little further down the query. i don't have much more white spaces i can delete and i'm only just getting into the Values(...) portion of it. the weird thing is. i copy and pasted just the columns portion and put it into Word and it comes up as being only about 3,000 characters, including white space.
am i missing something?
if it means anything, i'm running microsoft sql server 2005, and using the sql server management studio for editing
thanks!
See here: SQL Server: When 8000 Characters Is Not Enough for a couple of solutions
extremely abbreviated
Well, that doesn't really help since you have likely abbreviated away the cause of the issue.
If I were to guess, I have seen cases where NCHAR or CHAR variables/columns were involved. These expand to their full length when used in string concatenation and it will cause the final statement to be too long.
For what it's worth for style or otherwise, use NVarchar(Max) always for SQL Server 2005 and onwards. In fact, that is the expected type if you use sp_executesql.
If you check for fixed-width N/CHAR columns and switch to nvarchar(max), you may see the problem go away.
EDIT: Test showing NVarchar(Max) holding well in excess of 8000 bytes.
declare #sql nvarchar(max)
-- this CTE sets up the columns, 1 as field1, 2 as field2 etc
-- it creates 2000 columns
;with CTE(n, t) AS (
select 1, convert(nvarchar(max),'1 as field1')
union all
select n+1, convert(nvarchar(max),RIGHT(n, 12) + ' as field'+RIGHT(n, 12))
from cte
where N < 2000)
select #sql = coalesce(#sql+',','') + t
from CTE
option (maxrecursion 2000) -- needed, the default of 100 is not nearly enough
-- add the SELECT bit to make a proper SQL statement
set #sql = 'select ' + #sql
-- check the length : 33786
select LEN(#sql)
-- check the content
print #sql
-- execute to get the columns
exec (#sql)
Use an nvarchar(max) datatype for #sql.
How do you add a string to a column in SQL Server?
UPDATE [myTable] SET [myText]=' '+[myText]
That doesn't work:
The data types varchar and text are incompatible in the add operator.
You would use concat on MySQL, but how do you do it on SQL Server?
like said before best would be to set datatype of the column to nvarchar(max), but if that's not possible you can do the following using cast or convert:
-- create a test table
create table test (
a text
)
-- insert test value
insert into test (a) values ('this is a text')
-- the following does not work !!!
update test set a = a + ' and a new text added'
-- but this way it works:
update test set a = cast ( a as nvarchar(max)) + cast (' and a new text added' as nvarchar(max) )
-- test result
select * from test
-- column a contains:
this is a text and a new text added
Stop using the TEXT data type in SQL Server!
It's been deprecated since the 2005 version. Use VARCHAR(MAX) instead, if you need more than 8000 characters.
The TEXT data type doesn't support the normal string functions, while VARCHAR(MAX) does - your statement would work just fine, if you'd be using just VARCHAR types.
The + (String Concatenation) does not work on SQL Server for the image, ntext, or text data types.
In fact, image, ntext, and text are all deprecated.
ntext, text, and image data types will
be removed in a future version of
MicrosoftSQL Server. Avoid using these
data types in new development work,
and plan to modify applications that
currently use them. Use nvarchar(max),
varchar(max), and varbinary(max)
instead.
That said if you are using an older version of SQL Server than you want to use UPDATETEXT to perform your concatenation. Which Colin Stasiuk gives a good example of in his blog post String Concatenation on a text column (SQL 2000 vs SQL 2005+).
UPDATE test SET a = CONCAT(a, "more text")
hmm, try doing CAST(' ' AS TEXT) + [myText]
Although, i am not completely sure how this will pan out.
I also suggest against using the Text datatype, use varchar instead.
If that doesn't work, try ' ' + CAST ([myText] AS VARCHAR(255))
To Join two string in SQL Query use function CONCAT(Express1,Express2,...)
Like....
SELECT CODE, CONCAT(Rtrim(FName), " " , TRrim(LName)) as Title FROM MyTable
I am passing a comma-delimited list of values into a stored procedure. I need to execute a query to see if the ID of an entity is in the comma-delimited list. Unfortunately, I think I do not understand something.
When I execute the following stored procedure:
exec dbo.myStoredProcedure #myFilter=N'1, 2, 3, 4'
I receive the following error:
"Conversion failed when converting the varchar value '1, 2, 3, 4' to data type int."
My stored procedure is fairly basic. It looks like this:
CREATE PROCEDURE [dbo].[myStoredProcedure]
#myFilter nvarchar(512) = NULL
AS
SET NOCOUNT ON
BEGIN
-- Remove the quote marks so the filter will work with the "IN" statement
SELECT #myFilter = REPLACE(#myFilter, '''', '')
-- Execute the query
SELECT
t.ID,
t.Name
FROM
MyTable t
WHERE
t.ID IN (#myFilter)
ORDER BY
t.Name
END
How do I use a parameter in a SQL statement as described above? Thank you!
You could make function that takes your parameter, slipts it and returns table with all the numbers in it.
If your are working with lists or arrays in SQL Server, I recommend that you read Erland Sommarskogs wonderful stuff:
Arrays and Lists in SQL Server 2005
You need to split the string and dump it into a temp table. Then you join against the temp table.
There are many examples of this, here is one at random.
http://blogs.microsoft.co.il/blogs/itai/archive/2009/02/01/t-sql-split-function.aspx
Absent a split function, something like this:
CREATE PROCEDURE [dbo].[myStoredProcedure]
#myFilter varchar(512) = NULL -- don't use NVARCHAR for a list of INTs
AS
SET NOCOUNT ON
BEGIN
SELECT
t.ID,
t.Name
FROM
MyTable t
WHERE
CHARINDEX(','+CONVERT(VARCHAR,t.ID)+',',#myFilter) > 0
ORDER BY
t.Name
END
Performance will be poor. A table scan every time. Better to use a split function. See: http://www.sommarskog.se/arrays-in-sql.html
I would create a function that takes your comma delimited string and splits it and returns a single column table variable with each value in its own row. Select that column from the returned table in your IN statement.
I found a cute way of doing this - but it smells a bit.
declare #delimitedlist varchar(8000)
set #delimitedlist = '|1|2|33|11|3134|'
select * from mytable where #delimitedlist like '%|' + cast(id as varchar) + '|%'
So... this will return all records with an id equal to 1, 2, 33, 11, or 3134.
EDIT:
I would also add that this is not vulnerable to SQL injection (whereas dynamic SQL relies on your whitelisting/blacklisting techniques to ensure it isn't vulnerable). It might have a performance hit on large sets of data, but it works and it's secure.
I have a couple of blog posts on this as well, with a lot of interesting followup comments and dialog:
More on splitting lists
Processing list of integers
I was actually asked this myself a few weeks ago, whereas I know exactly how to do this with a SP or UDF but I was wondering if there was a quick and easy way of doing this without these methods. I'm assuming that there is and I just can't find it.
A point I need to make is that although we know what characters are allowed (a-z, A-Z, 0-9) we don't want to specify what is not allowed (##!$ etc...). Also, we want to pull the rows which have the illegal characters so that it can be listed to the user to fix (as we have no control over the input process we can't do anything at that point).
I have looked through SO and Google previously, but was unable to find anything that did what I wanted. I have seen many examples which can tell you if it contains alphanumeric characters, or doesn't, but something that is able to pull out an apostrophe in a sentence I have not found in query form.
Please note also that values can be null or '' (empty) in this varchar column.
Won't this do it?
SELECT * FROM TABLE
WHERE COLUMN_NAME LIKE '%[^a-zA-Z0-9]%'
Setup
use tempdb
create table mytable ( mycol varchar(40) NULL)
insert into mytable VALUES ('abcd')
insert into mytable VALUES ('ABCD')
insert into mytable VALUES ('1234')
insert into mytable VALUES ('efg%^&hji')
insert into mytable VALUES (NULL)
insert into mytable VALUES ('')
insert into mytable VALUES ('apostrophe '' in a sentence')
SELECT * FROM mytable
WHERE mycol LIKE '%[^a-zA-Z0-9]%'
drop table mytable
Results
mycol
----------------------------------------
efg%^&hji
apostrophe ' in a sentence
Sql server has very limited Regex support. You can use PATINDEX with something like this
PATINDEX('%[a-zA-Z0-9]%',Col)
Have a look at PATINDEX (Transact-SQL)
and Pattern Matching in Search Conditions
I found this page with quite a neat solution. What makes it great is that you get an indication of what the character is and where it is. Then it gives a super simple way to fix it (which can be combined and built into a piece of driver code to scale up it's application).
DECLARE #tablename VARCHAR(1000) ='Schema.Table'
DECLARE #columnname VARCHAR(100)='ColumnName'
DECLARE #counter INT = 0
DECLARE #sql VARCHAR(MAX)
WHILE #counter <=255
BEGIN
SET #sql=
'SELECT TOP 10 '+#columnname+','+CAST(#counter AS VARCHAR(3))+' as CharacterSet, CHARINDEX(CHAR('+CAST(#counter AS VARCHAR(3))+'),'+#columnname+') as LocationOfChar
FROM '+#tablename+'
WHERE CHARINDEX(CHAR('+CAST(#counter AS VARCHAR(3))+'),'+#columnname+') <> 0'
PRINT (#sql)
EXEC (#sql)
SET #counter = #counter + 1
END
and then...
UPDATE Schema.Table
SET ColumnName= REPLACE(Columnname,CHAR(13),'')
Credit to Ayman El-Ghazali.
SELECT * FROM TABLE_NAME WHERE COL_NAME LIKE '%[^0-9a-zA-Z $#$.$-$''''$,]%'
This works best for me when I'm trying to find any special characters in a string