Thousand separator (.) and decimal place with , in SQL sybase - numbers

I am having the problem that I should format any number in the following style in SQL ( Sybase ).
5123456789,99 --> 5.123.456.789,99
The only way that I found was:
select convert(varchar, cast(5123456789.99 as money), 1) --> 5,123,456,789.99
but this is the other way around :(
Is it somehow possible to get the thousand operator with a dot instead of comma?
Thank you very much!

This should work:
SELECT REPLACE(
REPLACE(
REPLACE(
CONVERT(varchar, CONVERT(money, 5123456789.99), 1), ',', ' '
), '.', ','
), ' ', '.'
);
It's not pretty though.

Related

Cannot cast int to varchar in STUFF while joining select

I am using stuff to join results of select. The columns I need to join are not constant and could change. So I put them in a variable and prepare a dynamic query.
SET #sql = N'Select #newvalues = STUFF( ( Select '','' + ' + #columns + ' FROM #MYINSERTED FOR XML PATH(''''),TYPE)
.value(''.'',''VARCHAR(MAX)''),1,2,'''')'
This query transforms into what looks like follows:
Select #newvalues = STUFF(
( Select ',' + ID, CaseID, DocumentType, FileName, FileExtension, FilePath, InsertDate, InsertedBy, ModifiedDate, ModifiedBy, OriginalFileName
FROM #MYINSERTED FOR XML PATH(''),TYPE)
.value(''.'',''VARCHAR(MAX)''),1,2,'')
But the first column ID is an integer and I get the following error.
Conversion failed when converting the varchar value ',' to data type int.
Please guide as to if there could be any workaround and I cannot cast each column individually as columns could change.
No reason to use STUFF, FOR XML PATH, etc. to merge the output of all columns into a single string. Simply make sure that all columns are explicitly cast when you construct your dynamic SQL.
How do you construct your #columns variable? I assume it contains something like "ID, CaseID, DocumentType, ...". You must construct a similar variable that does the explicit casting, or transform your #columns variable like this:
SET #columnsCast = 'CAST(' + REPLACE(#columns, ',', ' AS VARCHAR(MAX)) + '', '' CAST( ') + ' AS VARCHAR(MAX))'
This should make the #columnsCast variable look like this:
CAST(ID AS VARCHAR(MAX)) + ', ' + CAST(CaseID AS VARCHAR(MAX)) + ', ' + CAST(DocumentType AS VARCHAR(MAX)) + ', ' ...
Then simply perform a dynamic SQL statement like this:
SET #sql = N'DECLARE #newvalues AS VARCHAR(MAX) = '''';
SELECT #newvalues = #newvalues + ' + #columnsCast + ' FROM #MYINSERTED'
Then when you execute this expression, make sure to output #newvalues like this:
DECLARE #newvals AS VARCHAR(MAX)
EXECUTE sp_executesql #sql, N'#newvalues VARCHAR(MAX) OUTPUT', #newvalues=#newvals OUTPUT
SELECT #newvals

How to express PostgreSQL variable as a string

Is there any way how to express a variable in PostgreSQL as a string?
Example:
\set table_name countries
SELECT 'SELECT * FROM ' || CAST( :table_name, 'text' ) AS specificQuery;
leads to this error:
ERROR: syntax error at or near ","
LINE 1: SELECT 'SELECT * FROM ' || CAST( countries, 'text' ) AS specificQuery;
From the line sample above is obvious, that it doesn't convert "countries" to a string, but it is expressed as name of column/table.
How do I convert it?
Are you looking for something like this?:
SELECT * FROM :"table_name";
http://www.postgresql.org/docs/current/interactive/app-psql.html#APP-PSQL-VARIABLES
Something like this :
SELECT 'SELECT * FROM ' || countries::text AS specificQuery;

In SSMS copied string has different behaviour to original string

I am attempting to semi automate creation of my databases
As part of this I want to add extended properties of column descriptions.
When I try to run sp_sqlexec in my script ( or even just Exec(#mystring) I get an error. However, if while debugging, I copy the dynamic sql string from the watch window and then run sp_sqlexec on the copied string in a seperate window I get no errors and the extended properties are added correctly.
The following script demonstrates the problem:
--Create a table to apply column descriptions to
Create table dbo.table1 (id int, name nvarchar(20));
--Create the table that contains our column descriptions
Create table dbo.column_descs_table (schemaname nvarchar(20), tablename nvarchar(20), columnname nvarchar(20), column_description nvarchar(20))
Insert into column_descs_table (schemaname, tablename, columnname, column_description)
values ('dbo', 'table1', 'id', 'the id column'), ('dbo' , 'table1', 'name', 'the name column');
--Dynamic sql string varaible to hold the commands
Declare #dyn_sql nvarchar(max);
Set #dyn_sql = 'N'''; --Set to opening quote
--now create the string containing commands to add column escriptions
SELECT #dyn_sql = #dyn_sql + N' EXEC sp_addextendedproperty ''''Col Desc'''', ''''' + column_description + N''''', ''''SCHEMA'''', ' + schemaname + N', ''''TABLE'''', ' + tablename + N', ''''COLUMN'''', ' + columnname + N' ;'
FROM dbo.column_descs_table
Set #dyn_sql = #dyn_sql + ''''; --add the closing quote
Print #dyn_sql --If I copy the contents of #dyn_sql here and run seperately it works OK
Exec sp_sqlexec #dyn_sql -- this line causes error
The error I get is
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ' EXEC sp_addextendedproperty 'Col Desc', 'the id column', 'SCHEMA', dbo, 'TABLE', table1, 'COLUMN', id ; EXEC sp_addextendedprope'.
Yet if I step through the code and copy the contents of #dyn_sql then paste this as follows:
Exec sp_sqlexec N' EXEC sp_addextendedproperty ''Col Desc'', ''the id column'', ''SCHEMA'', dbo, ''TABLE'', table1, ''COLUMN'', id ; EXEC sp_addextendedproperty ''Col Desc'', ''the name column'', ''SCHEMA'', dbo, ''TABLE'', table1, ''COLUMN'', name ;'
Then the above works fine and the column descriptions are added as expected.
Any help on this specific copying problem is much appreciated. I do understand the security issues with dynamic sql ( this script will be removed from the database once my setup is complete)
Thanks in advance
Jude
It looks like it's because your leading N is included within the string to execute; you don't need it at all. In other words, you are ending up with something like this:
exec sp_execsql 'N'' exec sp_addextendedproperty /* etc. */ '''
But it should be like this:
exec sp_execsql N'exec sp_addextendedproperty /* etc. */ '
But why are you even using dynamic SQL here? All values passed to sp_addextendedproperty can be passed as parameters so there is no obvious reason to use dynamic SQL, unless you've simplified something for the question.
Finally, you should be using sp_executesql, it's the preferred way to execute dynamic SQL.
I believe that I have resolved my string copying problem. SQL was detecting double quotes in by concatenated string as empty strings and removing them. A simple example showing the problem and my solution is below:
--Example to Select 'simple string' and then 'concat string' into results sets
DECLARE
#Simplestring nvarchar( max ) = '' ,
#Concatstring nvarchar( max ) = '' ,
#Stringvar nvarchar( 10 ) = 'string';
--The double quotes in next line are the quotemark we want plus a quotemark acting
--as an escape character
--#simplestring will be set to 'Select 'simple string' '
SET #Simplestring = 'Select ''simple string'' ';
--Similarly we need #concatstring to be set to 'Select 'Concat string' '
SET #Concatstring = 'Select '' concat' + #Stringvar + ''; -- this wont work the last
--double quote will be removed
--Add a character that cannot appear in any othe part of the concatenation - I've used *
SET #Concatstring = 'Select '' Concat ' + #Stringvar + '*';
--Now replace the * with a quote mark
SET #Concatstring = REPLACE( #Concatstring , '*' , '''' ); -- This will work
EXEC sp_executesql #Simplestring;
EXEC sp_executesql #Concatstring;
There may be a simpler solution than mine.
Many thanks for the advice on using sp_executesql. I am working on changing my code to use this ( with variables passed in as parametrs).
Jude

Replace a newline in TSQL

I would like to replace (or remove) a newline character in a TSQL-string.
Any Ideas?
The obvious
REPLACE(#string, CHAR(13), '')
just won't do it...
Actually a new line in a SQL command or script string can be any of CR, LF or CR+LF. To get them all, you need something like this:
SELECT REPLACE(REPLACE(#str, CHAR(13), ''), CHAR(10), '')
REPLACE(#string, CHAR(13) + CHAR(10), '')
I may be a year late to the party, but I work on queries & MS-SQL every day, and I got tired of the built-in functions LTRIM() & RTRIM() (and always having to call them together), and of not catching 'dirty' data that had newlines at the end, so I decided it was high time to implement a better TRIM function. I'd welcome peer feedback!
Disclaimer: this actually removes (replaces with a single whitespace) extended forms of whitespace (tab, line-feed, carriage-return, etc.), so it's been renamed as "CleanAndTrim" from my original answer. The idea here is that your string doesn't need such extra special-whitespace characters inside it, and so if they don't occur at the head/tail, they should be replaced with a plain space. If you purposefully stored such characters in your string (say, your column of data that you're about to run this on), DON'T DO IT! Improve this function or write your own that literally just removes those characters from the endpoints of the string, not from the 'body'.
Okay, now that the disclaimer is updated, here's the code.
-- =============================================
-- Description: TRIMs a string 'for real' - removes standard whitespace from ends,
-- and replaces ASCII-char's 9-13, which are tab, line-feed, vert tab,
-- form-feed, & carriage-return (respectively), with a whitespace
-- (and then trims that off if it's still at the beginning or end, of course).
-- =============================================
CREATE FUNCTION [fn_CleanAndTrim] (
#Str nvarchar(max)
)
RETURNS nvarchar(max) AS
BEGIN
DECLARE #Result nvarchar(max)
SET #Result = LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
LTRIM(RTRIM(#Str)), CHAR(9), ' '), CHAR(10), ' '), CHAR(11), ' '), CHAR(12), ' '), CHAR(13), ' ')))
RETURN #Result
END
Cheers!
Another Disclaimer:
Your typical Windows line-break is CR+LF, so if your string contains those, you'd end up replacing them with "double" spaces.
UPDATE, 2016:
A new version that gives you the option to replace those special-whitespace characters with other characters of your choice! This also includes commentary and the work-around for the Windows CR+LF pairing, i.e. replaces that specific char-pair with a single substitution.
IF OBJECT_ID('dbo.fn_CleanAndTrim') IS NULL
EXEC ('CREATE FUNCTION dbo.fn_CleanAndTrim () RETURNS INT AS BEGIN RETURN 0 END')
GO
-- =============================================
-- Author: Nate Johnson
-- Source: http://stackoverflow.com/posts/24068265
-- Description: TRIMs a string 'for real' - removes standard whitespace from ends,
-- and replaces ASCII-char's 9-13, which are tab, line-feed, vert tab, form-feed,
-- & carriage-return (respectively), with a whitespace or specified character(s).
-- Option "#PurgeReplaceCharsAtEnds" determines whether or not to remove extra head/tail
-- replacement-chars from the string after doing the initial replacements.
-- This is only truly useful if you're replacing the special-chars with something
-- **OTHER** than a space, because plain LTRIM/RTRIM will have already removed those.
-- =============================================
ALTER FUNCTION dbo.[fn_CleanAndTrim] (
#Str NVARCHAR(MAX)
, #ReplaceTabWith NVARCHAR(5) = ' '
, #ReplaceNewlineWith NVARCHAR(5) = ' '
, #PurgeReplaceCharsAtEnds BIT = 1
)
RETURNS NVARCHAR(MAX) AS
BEGIN
DECLARE #Result NVARCHAR(MAX)
--The main work (trim & initial replacements)
SET #Result = LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
LTRIM(RTRIM(#Str)) --Basic trim
, NCHAR(9), #ReplaceTabWith), NCHAR(11), #ReplaceTabWith) --Replace tab & vertical-tab
, (NCHAR(13) + NCHAR(10)), #ReplaceNewlineWith) --Replace "Windows" linebreak (CR+LF)
, NCHAR(10), #ReplaceNewlineWith), NCHAR(12), #ReplaceNewlineWith), NCHAR(13), #ReplaceNewlineWith))) --Replace other newlines
--If asked to trim replacement-char's from the ends & they're not both whitespaces
IF (#PurgeReplaceCharsAtEnds = 1 AND NOT (#ReplaceTabWith = N' ' AND #ReplaceNewlineWith = N' '))
BEGIN
--Purge from head of string (beginning)
WHILE (LEFT(#Result, DATALENGTH(#ReplaceTabWith)/2) = #ReplaceTabWith)
SET #Result = SUBSTRING(#Result, DATALENGTH(#ReplaceTabWith)/2 + 1, DATALENGTH(#Result)/2)
WHILE (LEFT(#Result, DATALENGTH(#ReplaceNewlineWith)/2) = #ReplaceNewlineWith)
SET #Result = SUBSTRING(#Result, DATALENGTH(#ReplaceNewlineWith)/2 + 1, DATALENGTH(#Result)/2)
--Purge from tail of string (end)
WHILE (RIGHT(#Result, DATALENGTH(#ReplaceTabWith)/2) = #ReplaceTabWith)
SET #Result = SUBSTRING(#Result, 1, DATALENGTH(#Result)/2 - DATALENGTH(#ReplaceTabWith)/2)
WHILE (RIGHT(#Result, DATALENGTH(#ReplaceNewlineWith)/2) = #ReplaceNewlineWith)
SET #Result = SUBSTRING(#Result, 1, DATALENGTH(#Result)/2 - DATALENGTH(#ReplaceNewlineWith)/2)
END
RETURN #Result
END
GO
The Newline in T-SQL is represented by CHAR(13) & CHAR(10) (Carriage return + Line Feed). Accordingly, you can create a REPLACE statement with the text you want to replace the newline with.
REPLACE(MyField, CHAR(13) + CHAR(10), 'something else')
To do what most people would want, create a placeholder that isn't an actual line breaking character. Then you can actually combine the approaches for:
REPLACE(REPLACE(REPLACE(MyField, CHAR(13) + CHAR(10), 'something else'), CHAR(13), 'something else'), CHAR(10), 'something else')
This way you replace only once. The approach of:
REPLACE(REPLACE(MyField, CHAR(13), ''), CHAR(10), '')
Works great if you just want to get rid of the CRLF characters, but if you want a placeholder, such as
<br/>
or something, then the first approach is a little more accurate.
In SQL Server 2017 & later, use Trim
Select Trim(char(10) + char(13) from #str)
it trims on starting and ending, not in the middle
the order of \r and \n does not matter
I use it to trim special characters for a file name
Select Trim(char(10) + char(13) + ' *<>' from #fileName)
If your column data type is 'text' then you will get an error message as
Msg 8116, Level 16, State 1, Line 2 Argument data type text is
invalid for argument 1 of replace function.
In this case you need to cast the text as nvarchar and then replace
SELECT REPLACE(REPLACE(cast(#str as nvarchar(max)), CHAR(13), ''), CHAR(10), '')
Sometimes
REPLACE(myString, CHAR(13) + CHAR(10), ' ')
won't work. In that case use the following snippet code:
REPLACE(REPLACE(myString, CHAR(13),''), CHAR(10), ' ')
If you have an issue where you only want to remove trailing characters, you can try this:
WHILE EXISTS
(SELECT * FROM #ReportSet WHERE
ASCII(right(addr_3,1)) = 10
OR ASCII(right(addr_3,1)) = 13
OR ASCII(right(addr_3,1)) = 32)
BEGIN
UPDATE #ReportSet
SET addr_3 = LEFT(addr_3,LEN(addr_3)-1)
WHERE
ASCII(right(addr_3,1)) = 10
OR ASCII(right(addr_3,1)) = 13
OR ASCII(right(addr_3,1)) = 32
END
This solved a problem I had with addresses where a procedure created a field with a fixed number of lines, even if those lines were empty. To save space in my SSRS report, I cut them down.
If you have have open procedure with using sp_helptext then just copy all text in new sql query and press ctrl+h button use regular expression to replace and put ^\n in find field replace with blank .
for more detail check image.enter image description here
To #Cerebrus solution: for H2 for strings "+" is not supported. So:
REPLACE(string, CHAR(13) || CHAR(10), 'replacementString')
I was wanting to sanitize the contents of a column to generate a csv file, so want to get rid of the comma (,) within the varchar as well as newline and carrage-return.
I also wanted to eventually use the generated csv to create another script (to insert rows into another db) so also needed to change ' within the varchar to '' so ended up with this...
REPLACE(REPLACE(REPLACE(REPLACE(ErrorMessage, CHAR(13), ''), CHAR(10), ''),',',''),'''','''''')
There may be other nicer ways but it got the job done.
The answer posted above/earlier that was reported to replace CHAR(13)CHAR(10) carriage return:
REPLACE(REPLACE(REPLACE(MyField, CHAR(13) + CHAR(10), 'something else'), CHAR(13), 'something else'), CHAR(10), 'something else')
Will never get to the REPLACE(MyField, CHAR(13) + CHAR(10), 'something else') portion of the code and will return the unwanted result of:
'something else''something else'
And NOT the desired result of a single:
'something else'
That would require the REPLACE script to be rewritten as such:
REPLACE(REPLACE(REPLACE(MyField, CHAR(10), 'something else'), CHAR(13), 'something else'), CHAR(13) + CHAR(10), 'something else')
As the flow first tests the 1st/Furthest Left REPLACE statement, then upon failure will continue to test the next REPLACE statement.

TSQL varchar string manipulation

I have a variable which contains the following string: AL,CA,TN,VA,NY
I have no control over what I get in that variable (comes from reporting services)
I need to make it look like this: 'AL','CA','TN','VA','NY'
How do I do this?
declare #x varchar(50) = 'AL,CA,TN,VA,NY'
select '''' + REPLACE(#x, ',', ''',''') + ''''
I ended up doing something very similar that I thought I'd post. (I'll give credit to Mitch however)
This takes care of the middle:
SET #StateList = REPLACE(#StateList, ',', ''',''')
Then quote the edges:
SET #WhereClause1 = #WhereClause1 + 'AND customerState IN (''' + #StateList + ''') '
For a more generic answer, when you don't know what your output will look like exactly, use regular expressions.
This would let you you match on something like [A-Z]{2} and replace it with '$&'.
A commenter suggested this is overkill for this task - agreed, if you can guarantee you will always get a string like that. However, other people find these question pages later with similar, but not exact, problems, so other options are helpful to have.
Don't bother with dynamic sql.
You need to convert the string to a table
so
A,B,C,D
becomes
Value
A
B
C
D
using a function like
http://www.sqlusa.com/bestpractices/training/scripts/splitcommadelimited/
then you can use CROSS APPLY (which is like joining to a table, but a table created by a function) or you can just put it in a table variable and join to that
I want to know y does the following script run in SQL and not in T-SQL
DECLARE #tblName varchar(30)
SET #tblName = CONVERT(VARCHAR(20),GETDATE(),112) + 'Table'
DECLARE #sql nvarchar(4000)
SELECT #sql =
'CREATE TABLE "' + #tblName + '"
(
ID VARCHAR(15),
Name VARCHAR(15)
)'
EXEC(#sql)
go
it gives you the error
Msg 170, Sev 15: Line 1: Incorrect syntax near '20090714Table'. [SQLSTATE 42000]