I have some currency values stored in a table in a varchar(50) column. Unfortunately I cannot alter the data being imported, and the values are stored without decimal points. I need to get the values from the varchar column in a format where I can divide them by 100 to add the decimal. It would be awesome if I could just update the column to add the decimal.
I've tried CONVERTing and CASTing, yet when I divide by 100 it appears to simply truncate the two rightmost digits instead of actually performing the division.
Ultimately I just need the decimal points added to this column and am totally baffled.
Any help would be most appreciated!!
Thanks in advance!
Is this what you want:
declare #Currency as varchar(50)
set #Currency = 8000;
declare #CurrencyDecimal as decimal(18,2)
set #CurrencyDecimal = #Currency /100
select cast(#CurrencyDecimal as varchar(50))
and/or this:
select cast(#Currency / 100 as decimal(18,2) )
select convert(DECIMAL(18,2),#Currency / 100)
if you need to update:
update t1
set Currency = cast(Currency as decimal(18,2) )
where = -- some condition
Data Types (Transact-SQL)
CAST and CONVERT
I think you can use the STUFF function to respond to this request :
"It would be awesome if I could just update the column to add the decimal."
UPDATE [table] SET [column] = STUFF([column],LEN([column])-1,0,'.')
Related
I have a varchar column that has numbers with .0
This column has both numeric data and non-numeric data.
I first tried to convert data type to integer, but since there is non-numeric data type, it would not let me.
How do I remove .0 (from all numbers that has .0)?
So, for example, 100.0 should be 100
I am not trying to use select, cast or truncate as I need to actually modify the existing data.
Thanks.
Since the column has both numeric and non-numeric data it is not enough to just check if it ends with '.0'.
You should also check if it is a numeric value, which can be done with TRY_CAST():
UPDATE tablename
SET col = LEFT(col, LEN(col) - 2)
WHERE col LIKE '%.0' AND TRY_CAST(col AS FLOAT) IS NOT NULL
See the demo.
Assuming you want to update your table...
where x = your table name
yourfieldname = the field name you need to update.
.
UPDATE table X
SET yourfieldName = left(yourfieldname,len(yourieldName)-2)
WHERE right(yourfieldName,2)='.0')
-- or perhaps where yourfieldname like '%.0' would be faster...
Should: update all fields ending in .0 would need to test to see which where clause would be faster depending on indexes. if speed is a consideration. If not; and this is a 1 and done... does it matter?
Be sure to test on a subset/copy table!
Assumes you don't have a spaces after the .0... or any non-display characters.. If you do you'll need to trim off the spaces and replace the non-display characters with empty string ''
Just another option
Example
Declare #YourTable table (SomeCol varchar(50))
Insert Into #YourTable values
('100.0')
,('1001.0')
,('Not Numeric')
,('-200.05')
,('10,250.0')
Update #YourTable
set SomeCol = format(try_convert(money,SomeCol),'#.######')
From #YourTable
Where try_convert(money,SomeCol) is not null
The Updated Table
SomeCol
100
1001
Not Numeric
-200.05
10250
I update a ClientFunds.Balance table column with a value and use the Ouput Inserted.Balance clause to write the value to a log table.
Occasionally the value written to the ClientFunds table is truncated whilst the value written to the log table is always correct.
First, I fill this table with the details of what will be updated on the ClientFunds table:
declare #ToUpdate table
(
Id int identity(1,1),
ClientFundId int,
Total decimal (18, 2),
Rate decimal (10, 5)
);
This table will hold the data to be written to the log table:
declare #Updated as table
(
ClientFundId int,
AmountBefore decimal (18,2),
AmountAfter decimal (18,2),
ToUpdateId int
);
Here's how I update the ClientFunds table, using the #ToUpdate table and ouput the log information to the #Updated table. I've snipped a few details of the loop here but you should get the idea:
WHILE ##FETCH_STATUS = 0
BEGIN
update cf
set cf.Balance = cf.Balance - (up.Total * up.Rate)
OUTPUT INSERTED.Id, DELETED.Balance, INSERTED.Balance, up.Id
INTO #Updated
from #ToUpdate up
join dbo.ClientFunds cf on cf.Id = up.ClientFundId
where up.Id = #CurrentId
FETCH NEXT FROM ToUpdate_Cursor into #CurrentId;
END
Now, as I said, occasionally the dbo.ClientFunds.Balance value, which is decimal (18, 2), will be written to the db with the decimal part truncated yet the inserted value output to #ToUpdate retains the correct value.
For instance, one example is 14454.36 being written to the #Updated table, and ultimately the log file, but 14454.00 being written to dbo.ClientFunds.Balance.
Any idea of what could be happening?
Thanks,
Jules
I need to create a column witch will contain short guid. So I found out something like this:
alter table [dbo].[Table]
add InC UNIQUEIDENTIFIER not null default LEFT(NEWID(),6)
But I get the error:
Conversion failed when converting from a character string to uniqueidentifier.
I've been trying
LEFT(CONVERT(varchar(36),NEWID()),6)
and
CONVERT(UNIQUEIDENTIFIER,LEFT(CONVERT(varchar(36),NEWID()),6))
But I am still getting the same error.
There is no such thing as "short guid". Guid, or uniqueidentifier is a 16 byte data type. You can read about it in MSDN. It means that the length must always be 16 bytes and you cannot use 6 characters as you are trying to do.
In the same MSDN article you can find description how you can initialize this type:
A column or local variable of uniqueidentifier data type can be
initialized to a value in the following ways:
By using the NEWID function.
By converting from a string constant in the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, in which each x is a
hexadecimal digit in the range 0-9 or a-f. For example,
6F9619FF-8B86-D011-B42D-00C04FC964FF is a valid uniqueidentifier
value.
In your case you are trying to convert only 6 characters to uniqueidentifier which obviously fails.
If you want to use just 6 characters, just use varchar(6):
alter table [dbo].[Table]
add InC varchar(6) not null default LEFT(NEWID(),6)
Keep in mind that in this case this guid is not guaranteed to be unique.
Using CRYPT_GEN_RANDOM instead of NEWID can improve random distribution of the string.
SELECT LEFT(CAST(CAST(CRYPT_GEN_RANDOM(16) AS UNIQUEIDENTIFIER) AS VARCHAR(50)), 6)
I just made this one since I couldn't find a good answer on the internet.
Please keep in mind this is a 64 bit representation of a 128bit value, so it has twice the collision possibilities that a real GUID would have. Does not handle 0.
Function takes a NEWID value: 6A10A273-4561-40D8-8D36-4D3B37E4A19C
and shortens it to : 7341xIlZseT
DECLARE #myid uniqueidentifier= NEWID()
select #myid
DECLARE #bigintdata BIGINT = cast(cast(reverse(NEWID()) as varbinary(max)) as bigint)
DECLARE #charSet VARCHAR(70) = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
DECLARE #cBase int = LEN(#charSet)
DECLARE #sUID varchar(22) = ''
DECLARE #x int
WHILE (#bigintdata <> 0)
BEGIN
SET #x = CAST(#bigintdata % #cBase as INT) + 1
SET #bigintdata = #bigintdata / #cBase
SET #sUID = SUBSTRING(#charSet, #x, 1) + #sUID;
END
SELECT #sUID
I have a situation like this
I got a column with 'money' type, 2 decimal . Example data:(65.00)
I need to add 12 zero / 000000000000 to it so that the output would be like this:
(65.00 convert to 6500) + (000000000000) = 000000006500
Output: 000000006500
How can I achieve this?. Thank you for your help and suggestion
You can do this with a couple of casts, multiplying by 100, and using REPLICATE('0') to pad with the requisite number of zeroes).
I'm assuming you DO want up to 2 x trailing decimals, but no more.
DECLARE #value MONEY;
SET #value = 65.123;
DECLARE #intValue BIGINT;
SET #intValue = CAST(#value * 100.0 AS BIGINT);
SELECT REPLICATE('0',12-LEN(#intValue)) + CAST(#intValue AS NVARCHAR(20));
Returns 000000006512
If you need to do this on a set, a CTE can be used for the intermediate step, e.g.
WITH cte AS
(
SELECT CAST(MoneyField * 100.0 AS BIGINT) AS intValue
FROM SomeTable
)
SELECT
REPLICATE('0',12-LEN(cte.intValue)) + CAST(cte.intValue AS NVARCHAR(20))
FROM cte;
Fiddle here
It is Possible .But output Column should be in the type of varchar(15) .If you want to do further operation of your output you have to convert that into int or whatever
SELECT CONCAT(REPEAT('0',12-LENGTH(65.00)),(65.00*100));
declare #v nvarchar(50) = '21.89777777777777777777777777'
select convert(decimal(18,8),round(#v,3))
Unable to truncate the decimal values after rounded. eg in above question, it returns 21.8980000.
The resulting output must be like
21.898 when rounded by select convert(decimal(18,8),round(#v,3))
and 21.8988 when rounded by round(#v,4)
I have created an stored procedure from where i gets the round value. and it must trim the leading zeros after rounded. and It must be dynamic instead of changing the precision everytime
use a different precision for the decimal
declare #v nvarchar(50) = '21.89777777777777777777777777'
select convert(decimal(18,3),round(#v,3))
SQLFiddle demo
The value is the same, regardless if it's 21.8980000 or 21.898. It's the format that is different.
You should be formatting the value on the client, rather then on SQL Server.
Float will do your job
declare #v nvarchar(50) = '21.89777777777777777777777777'
select convert(float,round(#v,3))