| Author |
Topic |
|
sengoku
Starting Member
29 Posts |
Posted - 2003-06-19 : 10:59:11
|
| hello againthanks for all the help i've been getting on this board, you guys really know your stuff!anyway, what i'm after now is a function to do this :take a number with any number of digits, including after the decimal point, and put commas in every 3 digits to the left of the decimal.so1.33324 -> 1.333241000 -> 1,00010000.228 -> 10,000.228100000000 -> 100,000,000is there such a thing in SQL? i don't want to convert to a money datatype because that seems to round it to 2 decimal places...thanks in advance |
|
|
mr_mist
Grunnio
1870 Posts |
Posted - 2003-06-19 : 11:03:05
|
| You could do this in SQL, but it's a task that seems better suited to your presentation layer, or reporting tool.-------Moo. |
 |
|
|
macka
Posting Yak Master
162 Posts |
Posted - 2003-06-19 : 11:03:31
|
| Why do you need to do this in SQL Server. This is a presentation issue and should be handled from the front-end.macka.--There are only 10 types of people in the world - Those who understand binary, and those who don't. |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2003-06-19 : 11:04:40
|
| This is a job for the presentation layer, not SQL. how are you returning this data to the user? i.e., are you using ASP to write HTML or a report program like Access or Crystal? Use the formatting options in those applications.let me know if this doesn't make sense. SQL is not really designed to handle formatting of data.- Jeff |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2003-06-19 : 11:05:12
|
so, I guess we all agree then ! - Jeff |
 |
|
|
sengoku
Starting Member
29 Posts |
Posted - 2003-06-19 : 11:08:39
|
| hmmm, yes, i know it should be handled by the front end but the way it's been coded this would actually be more work - in this case the front end just takes whatever value is in the database and passes it to a string-parser proc, which slots it into a string for displaying... and as it stands the string-parser has no knowledge about what the data it's displaying is... which would be a bit of work to code in (loads of case statements :))so, thanks for the ideas, but is there anyway i can achieve this in sql? or am i spitting into the wind? :D |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2003-06-19 : 11:11:14
|
| What is the front end?- Jeff |
 |
|
|
sengoku
Starting Member
29 Posts |
Posted - 2003-06-19 : 11:15:04
|
| the front end is asp... but it's set up for easy changing of language, so everything it displays it just like this :"you have completed the [%1] stage of this process""you have made £[%1] from the slug-racing team""i think you are a [%1]"etc etcand then just does a replace on the [%1] with the results from a varchar field. so as you can see it would be rather more work to do it case-by-case in the asp, and actually easier in this case to do it in the db when it inserts whatever into the varchar field :) |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2003-06-19 : 12:14:57
|
| hate to say it, but you need to add the functionalilty to your presentation layer.Like you said, there is a function or procedure in your ASP scripts that put the arguments into the string in place of the [%1] placeholders, and I think you need to add a little more functionality to that script.For example, right now it just takes the argument and puts it in place of the [%1], but why not have the function handle this case:[%1, <some format>]and in the <some format> part you can have some indicator of how it should be formatted. I would need to see the function that does the current substitution to help you further. - Jeff |
 |
|
|
Amethystium
Aged Yak Warrior
701 Posts |
Posted - 2003-06-20 : 06:08:52
|
Here is a function that would format your numbers the way you want.CREATE FUNCTION DBO.FORMATNUMBER (@VALUE NUMERIC(19,6)) RETURNS VARCHAR(100) AS BEGIN DECLARE @PART1 VARCHAR(100) -- HOLDS ALL THE DIGITS ON THE LEFT OF THE DICMAL PLACEDECLARE @PART2 VARCHAR(100) -- GOLD ALL DIGITS ON THE RIGHT SIDE OF THE DECIMAL PLACEDECLARE @HOLDER VARCHAR(100) -- HOLD THE MAIN NUMBERDECLARE @COUNTER INT -- COUNTER FOR THE WHILE LOOP DECLARE @FLG INT -- INDICATOR FOR POSITIVE/NEGATIVE NUMBERSSET @FLG = 0IF @VALUE < 0 BEGINSET @FLG = 1ENDSET @HOLDER = (CONVERT(VARCHAR(100),ABS(@VALUE))) SET @PART1 = SUBSTRING(@HOLDER, 1, CHARINDEX('.', @HOLDER)-1) SET @PART1 = REVERSE(@PART1) SET @PART2 = SUBSTRING(@HOLDER, CHARINDEX('.', @HOLDER),LEN(@HOLDER)-CHARINDEX('.', @HOLDER)+1) SET @COUNTER = 1 SET @HOLDER = '' WHILE @COUNTER <= LEN(@PART1) BEGIN IF @COUNTER%3 = 0 BEGIN SELECT @HOLDER = @HOLDER + SUBSTRING(@PART1, @COUNTER, 1)+',' END ELSE BEGIN SELECT @HOLDER = @HOLDER + SUBSTRING(@PART1, @COUNTER, 1) END SET @COUNTER = @COUNTER + 1 END IF SUBSTRING(REVERSE(@HOLDER), 1, 1) = ',' BEGIN SET @HOLDER = SUBSTRING(@HOLDER, 1, LEN(@HOLDER)-1) ENDIF @FLG = 1 RETURN '-'+REVERSE(@HOLDER)+CASE WHEN CAST(@PART2 AS NUMERIC(19,4)) = 0 THEN '' ELSE @PART2 END RETURN REVERSE(@HOLDER)+CASE WHEN CAST(@PART2 AS NUMERIC(19,4)) = 0 THEN '' ELSE @PART2 ENDEND Example,SELECT DBO.FORMATNUMBER(100000000) = 100,000,000SELECT DBO.FORMATNUMBER(120000.2584) = 120,000.258400note that I have set the accuracy to 6 decimal places hence the two extra 0s in the second statment.This will now take care of positive as well as negative numbers. Cheers MistyGood Luck!Edited by - Amethystium on 06/20/2003 06:32:26Edited by - Amethystium on 06/20/2003 10:36:26 |
 |
|
|
mr_mist
Grunnio
1870 Posts |
Posted - 2003-06-20 : 06:15:13
|
| Nice function. It has some problems with negative numbers, I don't know if that is a requirement, if so it might need some extra code to handle the -select dbo.formatnumber (-412)-,412select dbo.formatnumber (-126412)-,126,412I imagine negatives would need to be converted to a positive number then translated with the commas and then have the - stuck on the front again. Or something.-------Moo. |
 |
|
|
Amethystium
Aged Yak Warrior
701 Posts |
Posted - 2003-06-20 : 06:18:47
|
quote: Nice function. It has some problems with negative numbers, I don't know if that is a requirement, if so it might need some extra code to handle the -select dbo.formatnumber (-412)-,412select dbo.formatnumber (-126412)-,126,412I imagine negatives would need to be converted to a positive number then translated with the commas and then have the - stuck on the front again. Or something.-------Moo.
Well spotted Misty.For some reason I ignored negatives, but I will make the changes now.Good Luck! |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2003-06-20 : 08:03:00
|
| Funny, you can write a nice long complex UDF (that only works in SQL Server 2000) that must run on every row and then eventually returns to the client a varchar() instead of the actual number -- which means you can't do math with it, or subtotal it later on, or do any comparisions with it -- or you can do this in your ASP page:response.write FormatCurrency(r("ColumnName"),2,,true,true)I'd go with option #2.I know I sound like a broken record sometimes, but I can stress enough how you should not spend any time writing SQL code to do formatting ... just return the results.- JeffEdited by - jsmith8858 on 06/20/2003 08:10:32 |
 |
|
|
Page47
Master Smack Fu Yak Hacker
2878 Posts |
Posted - 2003-06-20 : 08:29:11
|
Fun with tally tables ...declare @n decimal(20,8), @c varchar(20)select @n = -417543678.2425select @c = coalesce(@c,'') + mfrom ( select top 100 percent n, case when n%10 = 0 then substring(convert(varchar,@n),n/10,1) when (n/10) < charindex('.',convert(varchar,@n))-1 and ((n/10) - charindex('.',convert(varchar,@n))+1)%3=0 and n%5 = 0 and substring(convert(varchar,@n),(n/10),1) <> '-' then ',' else null end as m from dbo.tally where n/10<=len(convert(varchar,@n)) and n >= 10 order by n) nwhere m is not nullorder by nselect @c Jay White{0} |
 |
|
|
Amethystium
Aged Yak Warrior
701 Posts |
Posted - 2003-06-20 : 08:38:10
|
| That is wicked Page47. Nicely done sir.Tally... tally.. tally... telly..I never know how/when to use them.P.S.Some weird stuff about number 47. Intersting website I have to say.Good Luck! |
 |
|
|
Page47
Master Smack Fu Yak Hacker
2878 Posts |
Posted - 2003-06-20 : 08:58:34
|
I should note that in this case I completely agree with Jeff and others that formatting is the job of the presentation layer ... I just saw the function and had to write a set-based version Jay White{0} |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2003-06-20 : 09:03:04
|
| very nice, Jay ...not to be picky, but I hope we all know that in cases like this the set-based method would be much slower than a simple iterative loop .... you shouldn't add I/O or access to database tables to a UDF if it doesn't need it.having said that, it is definitely a cool solution !- JeffEdited by - jsmith8858 on 06/20/2003 09:03:25 |
 |
|
|
Amethystium
Aged Yak Warrior
701 Posts |
Posted - 2003-06-20 : 09:17:39
|
quote: I should note that in this case I completely agree with Jeff and others that formatting is the job of the presentation layer ... I just saw the function and had to write a set-based version Jay White{0}
In other words, my UDF sucks right?P.S.I just saw your profile Page47. My uncle lives in the same area!Edited by - Amethystium on 06/20/2003 09:20:44 |
 |
|
|
Page47
Master Smack Fu Yak Hacker
2878 Posts |
Posted - 2003-06-20 : 10:01:27
|
No, actually, mine sucks ...Consider a tally table with 1000 rows ...declare @t datetimeset @t = getdate()--my version of the functionselect dbo.formatnumber2(rand(convert(binary(4),newid()))* t1.n * 10000) from tally t1select datediff(ms,@t,getdate())set @t = getdate()select dbo.formatnumber(rand(convert(binary(4),newid()))* t1.n * 10000) from tally t1select datediff(ms,@t,getdate()) Mine is taking about 1300 ms to format 1000 random numbers ... yours seems to do the same job in about 60 ms ...Jay White{0} |
 |
|
|
jsmith8858
Dr. Cross Join
7423 Posts |
Posted - 2003-06-20 : 10:02:41
|
| nothing is wrong with the UDF at all ... it technically works fine, it is just that choosing to solve this particular problem (or any formatting problem for that matter) within SQL server is NOT a good way to do it ... do it at the presentation layer.- Jeff |
 |
|
|
Amethystium
Aged Yak Warrior
701 Posts |
Posted - 2003-06-20 : 10:22:56
|
quote: nothing is wrong with the UDF at all ... it technically works fine, it is just that choosing to solve this particular problem (or any formatting problem for that matter) within SQL server is NOT a good way to do it ... do it at the presentation layer.- Jeff
I guess that is something that I am beginning to realise more and more as I learn more about SQL Server. Cosmetic issues should be left to the presentation layer as you put it. Good advice if you ask me, still, it was fun writing the UDF.Good Luck! |
 |
|
|
Next Page
|