SSMS and SQLCMD displays only the first 8000 characters - sql-server-2005

In SSMS when I try to execute:
SELECT CONVERT(VARCHAR(MAX), REPLICATE('a',9000))
I see only the first 8000 characters displayed. The settings Tool >> Options >> Query Results >> Sql Server >> Results to Grid is set to 65534 and Results to Text is set to 8192.
Also when I try to run this from SQLCMD
sqlcmd -S Server -E -y 0 -Q "SELECT CONVERT(VARCHAR(MAX), REPLICATE('a',9000))" -o out.txt
I see only 8000 charecters.
The flag -y 0 is supposed to set it up to 1 MB. But I do not more than 8000 characters.
What could be the problem?
thanks,
_UB

REPLICATE output is based on the datatype input. So this explains sqlcmd.
If string expression is not of type varchar(max) or nvarchar(max),
REPLICATE truncates the return value
at 8,000 bytes. To return values
greater than 8,000 bytes,
string expression must be explicitly
cast to the appropriate large-value
data type.
So, use this SELECT REPLICATE(CONVERT(VARCHAR(MAX), 'a'), 9000)
And SSMS has never shown all text data (nor did Query Analyzer)

See here :
http://www.sqlservercentral.com/articles/varchar(max)/67057/

VARCHAR(MAX) is only capable of holding 8000 characters
see here
From MSDN:
varchar [ ( n | max ) ] -
Variable-length, non-Unicode character
data. n can be a value from 1 through
8,000. max indicates that the maximum
storage size is 2^31-1 bytes
As Joseph (below) says, to hold more, use a text or ntext data type, but if you want to be able to search that, then you'd need some form of full-text indexing enabled.
Better Link

Related

SQL Server adding extra special characters in query result

I am trying to extract some records in a file using BCP command in SQL Server. However when the file is generated, there are extract spaces in between the result for each column.
To try I just wrote basic SQL Query as simple as this
select 'ABC', 40, 'TEST','NOTWORKING'
When we copy the output of above query and paste it in Notepad, the output comes as
ABC 40 TEST NOTWORKING
Notice the space between each value? The file that system is generating using BCP command also has same space coming in the output file which is incorrect. What I want to see in the output file is
ABC40TESTNOTWORKING
What must be causing this issue? I am simply amazed to see such weird issue and hoping that it can be fixed by some changes or setting. Please help.
Sample BCP command
EXEC xp_cmdshell 'bcp "select ''ABC'', 40, ''TEST'',''NOTWORKING''" queryout "E:\Testfile.txt" -c -T -S""'
Output in the File - Testfile.txt
ABC 40 TEST NOTWORKING
There are probably tabs between the values. If you want a single value, use concat():
select CONCAT('ABC', 40, 'TEST', 'NOTWORKING')
There's no issue. The command line has no field terminator argument, so the default is used, a tab. That's described in the docs :
-t field_term
Specifies the field terminator. The default is \t (tab character). Use this parameter to override the default field terminator. For more information, see Specify Field and Row Terminators (SQL Server).
If you specify the field terminator in hexadecimal notation in a bcp.exe command, the value will be truncated at 0x00. For example, if you specify 0x410041, 0x41 will be used.
If field_term begins with a hyphen (-) or a forward slash (/), do not include a space between -t and the field_term value.
The link points to an entire article that explains how to use terminators, for each of the bulk operations.
As for the Copy/Paste operation, it has nothing to do with SQL Server. SQL Server has no UI, it's a service. I suspect what was pasted in Notepad was copied from an SSMS grid.
SSMS is a client tool just like any other. When you copy data from it into the clipboard, it decides what to put there and what format to use. That format can be plain text, using spaces and tabs for layout, RTF, HTML etc.
Plain text with tabs as field separators is probably the best choice for any tool, as it preserves the visual layout up to a point and uses only a single character as a separator. A fixed-length layout using spaces could also be used but that would add characters that may well be part of a field.
Encodings and codepages
-c exports the data using the user's default codepage. This means that text stored in varchar fields using a different codepage (collation) may get mangled. Non-visible Unicode characters will also get mangled and appear as something else, or as ?.
-c
Performs the operation using a character data type. This option does not prompt for each field; it uses char as the storage type, without prefixes and with \t (tab character) as the field separator and \r\n (newline character) as the row terminator. -c is not compatible with -w.
It's better to use export the file as UTF16 using -w.
-w
Performs the bulk copy operation using Unicode characters. This option does not prompt for each field; it uses nchar as the storage type, no prefixes, \t (tab character) as the field separator, and \n (newline character) as the row terminator. -w is not compatible with -c.
The codepage can be specified using the -C parameter. -C 1251 for example will export the data using Windows' Latin1 codepage. 1253 will export it using the Greek codepage.
-C { ACP | OEM | RAW | code_page }
Specifies the code page of the data in the data file. code_page is relevant only if the data contains char, varchar, or text columns with character values greater than 127 or less than 32.
SQL Server 2016 and later can also export text as UTF8 with -C 65001. Earlier versions don't support UTF8.
Versions prior to version 13 (SQL Server 2016 (13.x)) do not support code page 65001 (UTF-8 encoding). Versions beginning with 13 can import UTF-8 encoding to earlier versions of SQL Server.
All this is described in bcp's online documentation.
This subject is so important for any database that it has an entire section in the docs, that describes data format and considerations, using format files to specify different settings per column, and guidelines to ensure compatibility with other applications

EncryptByPassPhrase returns special characters

I'm trying to encrypt with EncryptByPassPhrase in SQL Server 2012 but when I execute this function I get values like "öK{8+¨´¡¿" ... maybe someone can help me?.
This is the code that i'm using:
IF(#MODE = 1)
BEGIN
SET #RESUL = convert(varchar(100),ENCRYPTBYPASSPHRASE('Prueba','200000'))<br>
PRINT 'ENCRYPT'+ (CAST(#RESUL AS varchar(20)))
END
Let's break it down. According to the documentation, the output of ENCRYPTBYPASSPHRASE() is varbinary. You're CONVERTing that to varchar. According to the documenation for convert, if you don't provide a style, convert "Translates ASCII characters to binary bytes or binary bytes to ASCII characters. Each character or byte is converted 1:1.". If you're looking for something more like 0x123abc, pass an additional parameter (1) to CONVERT to make it do that.
All that said, unless you need a human to be able to transcribe the encrypted content (or otherwise interpret it), I'd leave it in its varbinary representation. Less room for error on the decryption side. Specifically:
DECLARE #resul VARBINARY(8000);
SET #RESUL = ENCRYPTBYPASSPHRASE('Prueba','200000');
SELECT CAST(DECRYPTBYPASSPHRASE('Prueba', #resul) AS VARCHAR(50));

Removing hidden character at end of SQL server field

I have a strange situation displaying value from SQL server. There is a value stored in SQL server 2008 field which is hidden when queried from server and shown in Management Studio (see below).
Test template 2​
But when displayed on a screen in HTML editor it is showing as ? (see below)
Test template 2?
When I check for ascii value it shows 63. Not sure how user got this special value into this field in SQL server. When I test by entering ? into input field and display it works fine without any issues.
I don't want to blindly remove last character from this field. I am trying to determine a solution to identify this invisible value and remove it either while storing or displaying.
Any solution is greatly appreciated.
As comments below suggests this turned out to be Unicode 8203 (zero width space).
My next question is how to replace this Unicode 8203 in one statement in T-SQL without parsing through each character?
Use REPLACE to remove the zero-width space character:
-- setup unicode string containing zero-width character
DECLARE #UnicodeReplace NVARCHAR(5) = N'Test' + NCHAR(8203);
-- check that unicode string length is 5,
-- and prove existence of zero-width space character matching unicode 8203
SELECT #UnicodeReplace AS String,
LEN(#UnicodeReplace) AS Length,
UNICODE(SUBSTRING(#UnicodeReplace, 5, 1)) AS UnicodeValue
-- replace and prove the unicode string length is reduced to 4
SELECT REPLACE(#UnicodeReplace, NCHAR(8203), N''),
LEN(REPLACE(#UnicodeReplace, NCHAR(8203), N'')) AS Length;
SQL Fiddle
Such characters could not be replaced if database collation has default values like this: SQL_Latin1_General_CP1_CI_AS. In such cases this command could work:
set #word=replace(#word collate Latin1_General_100_BIN2, nchar(8205),N'')

Sqlcmd trailing spaces in output file

Here is my simplified scenario:
I have a table in SQL Server 2005 with single column of type varchar(500). Data in the column is always 350 characters in length.
When I run a select on it in SSMS query editor, copy & paste the result set in to a text file, the line length in the file is 350, which matches the actual data length.
But when I use sqlcmd with the -o parameter, the resulting file has line length 500, which matches the max length of varchar(500).
So question is, without using any string functions in select, is there a way to let sqlcmd know not to treat it like char(500) ?
You can use the sqlcmd formatting option -W to remove trailing spaces from the output file.
Read more at this MSDN article.
-W only works with default size of 256 for variable size columns. If you want more than that you got to use -y modifier which will tell you its mutually exclusive with -W. Basically you are out of luck and as in my case file grows from 0.5M to 172M. You have to use other ways to strip white space post file generation. Some PowerShell command or something.

How to output data from iSQL to csv file _with_ headings?

I'm trying to query a Sybase ASA 8 database with the iSQL client and export the query results to a text file in CSV format. However the column headings are not exported to the file. There is no special option to specify that, neither in the iSQL settings nor in the OUTPUT statement.
The query and output statement looks like this:
SELECT * FROM SomeTable;
OUTPUT TO 'C:\temp\sometable.csv' FORMAT ASCII DELIMITED BY ';' QUOTE ''
The result is a file like
1;Miller;Steve;1980-06-28
2;Jones;Martha;1965-11-02
3;Waters;Richard;1979-10-15
while I'd like to have
ID;LASTNAME;FIRSTNAME;DOB
1;Miller;Steve;1980-06-28
2;Jones;Martha;1965-11-02
3;Waters;Richard;1979-10-15
Any hints?
I would have suggested to start with another statement:
SELECT 'ID;LASTNAME;FIRSTNAME;DOB' FROM dummy;
OUTPUT TO 'C:\\temp\\sometable.csv' FORMAT ASCII DELIMITED BY ';' QUOTE '';
and add the APPEND option on your query... but I can't get APPEND to work (but I'm using a ASA 11 engine).
Try this one
SELECT 'ID','LASTNAME','FIRSTNAME','DOB' union
SELECT string(ID),LASTNAME,FIRSTNAME,DOB FROM SomeTable;
OUTPUT TO 'C:\\temp\\sometable.csv' FORMAT ASCII DELIMITED BY ';' QUOTE '';
Simply add the option
WITH COLUMN NAMES
to your statement and it adds a header line with the column names.
The complete statement is therefore:
SELECT * FROM SomeTable; OUTPUT TO 'C:\temp\sometable.csv' FORMAT ASCII DELIMITED BY ';' QUOTE '' WITH COLUMN NAMES
See sybase documentation.
I am able to use the isql command to output quoted CSV.
Example
$ isql $DATABASE $USERNAME $PASSWORD -b -d, -q -c
select username, fullname from users
gives the result:
username,fullname
"jdoe","Jane Doe"
"msmith","Mark Smith"
Command-line flags
(copied from the man page)
-b: Run isql in non-interactive batch mode. In this mode, the isql processes its standard input, expecting one SQL command per line.
-dDELIMITER: Delimits columns with delimiter.
-c: Output the names of the columns on the first row. Has any effect only with the -d or -x options.
-q: Wrap the character fields in double quotes.
Escaping Issue
You might run into problems if the query results contain double-quotes, though. The quotes aren't escaped properly, so they result in invalid CSV:
> select 'string","with"quotes' as quoted_string
quoted_string
"string","with"quotes"
You are already familiar with the OUTPUT options. There is no option that gives you what you want.
Ok, the problem is the receiving end does not accept standard CSV files, it needs semi-colons.
If you are scripting, then you are better off getting the output in the format that is closest to what you need, and then awk-ing the output file. Very fast and you can change anything you need. I think your best option is ASCII or default output format, which will provide Comma (not colon) Separated Values, in an ASCII character text file, and includes column Headers. Then use a single awk command to convert the commas to semi-colons.
Found an easier solution, Place the headers in one file say header.txt ( it will contain a single line "col_1|col_2|col_3") then to combine the header file and your output file run:
cat header.txt my_table.txt > my_table_wth_head.txt
isql -S<Server> -D<Database>-U<UserName> -s \; -P<password>\$\1 -w 10000 -iname.sql > output.csv
If you use the FORMAT EXCEL option, it will output the rows with the column name in the first row. Then once you get it into excel you can save it into another format if you need to.
SELECT * FROM SOMETABLE;
OUTPUT TO 'C:\temp\sometable.xls' FORMAT EXCEL DELIMITED BY ';' QUOTE ''
Recently I needed to solve similar issue with some prehistoric ASA7 which does not support the WITH COLUMN NAMES for .CSV output.
The solution for me was the .DBF file, which has the columns structure in it and can be processed automatically, much better than .XLS
SELECT * FROM SomeTable;
OUTPUT TO 'C:\temp\sometable.dbf' FORMAT DBASEIII;