This article gives you all the information you need in order to begin working with numbers in your PL/SQL programs.

Numbers in PL/SQL

PL/SQL offers a variety of numeric datatypes to suit different purposes:

  • NUMBER. A true decimal datatype that is ideal for working with monetary amounts. NUMBER is the only one of PL/SQL’s numeric types to be implemented in a platform-independent fashion.

  • PLS_INTEGER. Integer datatype conforming to your hardware’s underlying integer representation. Arithmetic is performed with your hardware’s native machine instructions. You cannot store values of this type in tables; it is a PL/SQL-specific datatype.

  • SIMPLE_INTEGER.Introduced as of Oracle Database 11g Release 1. The SIMPLE_INTEGER datatype results in significantly shorter execution times for natively compiled code. This datatype is not explored in this article.

  • BINARY_FLOAT and BINARY_DOUBLE. Single- and double-precision, IEEE-754, binary floating-point datatypes. These BINARY datatypes are highly specialized and are useful when you need to improve the performance of computation-intensive operations. These datatypes are not explored in this article.

In practice, you may encounter other numeric types, such as FLOAT, INTEGER, and DECIMAL. These are subtypes of the four core numeric types in the preceding list.

Now let’s take a closer look at NUMBER and PLS_INTEGER.

The NUMBER datatype. The NUMBER data-type is by far the most common numeric datatype you’ll encounter in the world of Oracle and PL/SQL programming. Use it to store integer, fixed-point, or floating-point numbers of just about any size. Prior to Oracle Database 10g, NUMBER was the only numeric datatype supported directly by the Oracle Database engine; now you can use BINARY_FLOAT and BINARY_DOUBLE as well. NUMBER is implemented in a platform-independent manner, and arithmetic on NUMBER values yields the same result no matter what hardware platform you run on.

To work with numbers in PL/SQL programs, you declare variables to hold the number values. The following declares a variable using the NUMBER datatype:

DECLARE
l_salary NUMBER;
 

This range of values is demonstrated by the code block in Listing 1. (TO_CHAR and format masks are described later in this article.)Such a declaration results in a floating-point number. Oracle Database will allocate space for a maximum of 40 digits, and the decimal point will float to best accommodate whatever values you assign to the variable. NUMBER variables can hold values as small as 10-130 (1.0E - 130) and as large as 10126 - 1 (1.0E126 - 1). Values smaller than 10-130 will get rounded down to 0, and calculations resulting in values larger than or equal to 10126 will be un-defined, causing runtime problems but not raising an exception.

Code Listing 1: Demonstration of the range of NUMBER datatype values

DECLARE
tiny_nbr NUMBER := 1e-130;
test_nbr NUMBER; -- 1111111111222222222233333333334
-- 1234567890123456789012345678901234567890
big_nbr NUMBER := 9.999999999999999999999999999999999999999e125; -- 1111111111222222222233333333334444444
-- 1234567890123456789012345678901234567890123456
fmt_nbr VARCHAR2(50) := '9.99999999999999999999999999999999999999999EEEE';
BEGIN
DBMS_OUTPUT.PUT_LINE(
'tiny_nbr =' || TO_CHAR(tiny_nbr, '9.9999EEEE')); /* NUMBERs that are too small round down to zero. */
test_nbr := tiny_nbr / 1.0001;
DBMS_OUTPUT.PUT_LINE(
'tiny made smaller =' || TO_CHAR(test_nbr, fmt_nbr)); /* NUMBERs that are too large throw an error: */
DBMS_OUTPUT.PUT_LINE(
'big_nbr =' || TO_CHAR(big_nbr, fmt_nbr));
test_nbr := big_nbr * 1.0001; -- too big
DBMS_OUTPUT.PUT_LINE(
'big made bigger =' || TO_CHAR(test_nbr, fmt_nbr));
END; And here is the output from this block: tiny_nbr = 1.0000E-130
tiny made smaller = .00000000000000000000000000000000000000000E+00
big_nbr = 9.99999999999999999999999999999999999999900E+125
big made bigger =#################################################

If you try to explicitly assign a number that is too large to your NUMBER variable, you’ll raise a numeric overflow or underflow exception, but if you assign calculation results that exceed the largest legal value, no exception will be raised. If your application really needs to work with such large numbers, you will need to write validation routines that anticipate out-of-range values or consider using BINARY_DOUBLE. Using binary datatypes has rounding implications, so be sure to check the Oracle documentation on binary datatypes for details. For most uses, the chance of encountering these rounding errors will probably lead you to choose the NUMBER datatype.

Often when you declare a variable of type NUMBER, you will want to constrain its precision and scale, which you can do as follows:

NUMBER (precision, scale)

For example, I want to declare a variable to hold a monetary amount of up to $999,999 and that consists of dollars and cents (that is, just two digits to the right of the decimal point). This declaration does the trick:

NUMBER (8,2)

Such a declaration results in a fixed-point number. The precision is the total number of significant digits in the number. The scale dictates the number of digits to the right (positive scale) or left (negative scale) of the decimal point and also affects the point at which rounding occurs. Both the precision and scale values must be literal integer values; you cannot use variables or constants in the declaration. Legal values for precision range from 1 to 38, and legal values for scale range from -84 to 127.

When declaring fixed-point numbers, the value for scale is usually less than the value for precision.

The PLS_INTEGER datatype. The PLS_INTEGER datatype stores signed integers in the range of -2,147,483,648 through 2,147,483,647. Values are represented in your hardware platform’s native integer format.

Here is an example of declaring a variable of type PLS_INTEGER:

DECLARE
loop_counter PLS_INTEGER;

The PLS_INTEGER datatype was designed for speed. When you perform arithmetic with PLS_INTEGER values, the Oracle software uses native machine arithmetic. As a result, it’s faster to manipulate PLS_INTEGER values than it is to manipulate integers in the NUMBER datatype.

Consider using PLS_INTEGER whenever your program is compute-intensive and involves integer arithmetic (and the values will never fall outside of this type’s range of valid integers). Bear in mind, however, that if your use of PLS_INTEGER results in frequent conversions to and from the NUMBER type, you may be better off using NUMBER to begin with. You’ll gain the greatest efficiency when you use PLS_INTEGER for integer arithmetic (and for loop counters) in cases in which you can avoid conversions back and forth with the NUMBER type.

Numeric Built-in Functions

Oracle Database includes an extensive set of built-in functions for manipulating numbers and for converting between numbers and strings. The following are some of the most commonly needed functions.

ROUND. The ROUND function accepts a number and returns another number rounded to the specified number of places to the right of the decimal point. If you do not specify that number, ROUND will return a number rounded to the nearest integer.

Listing 2 includes some examples of calls to ROUND.

Code Listing 2: Calls to ROUND

BEGIN
DBMS_OUTPUT.put_line (ROUND (10.25));
DBMS_OUTPUT.put_line (ROUND (10.25, 1));
DBMS_OUTPUT.put_line (ROUND (10.23, 1));
DBMS_OUTPUT.put_line (ROUND (10.25, 2));
DBMS_OUTPUT.put_line (ROUND (10.25, -2));
DBMS_OUTPUT.put_line (ROUND (125, -2));
END; And here is the output from this block: 10
10.3
10.2
10.25
0
100

Note that a negative value for the second argument rounds to the nearest 10 (to the left of the decimal point).

TRUNC. TRUNC is similar to round, in that you can specify the number of digits to the right or left of the decimal point. The difference is that TRUNC simply removes or truncates digits. And, like ROUND, you can specify a negative number, which truncates digits (makes them zero) to the left of the decimal point.

Listing 3 includes some examples of calls to TRUNC.

Code Listing 3: Calls to TRUNC

BEGIN
DBMS_OUTPUT.put_line (TRUNC (10.23, 1));
DBMS_OUTPUT.put_line (TRUNC (10.25, 1));
DBMS_OUTPUT.put_line (TRUNC (10.27, 1));
DBMS_OUTPUT.put_line (TRUNC (123.456, -1));
DBMS_OUTPUT.put_line (TRUNC (123.456, -2));
END; And here is the output from this block: 10.2
10.2
10.2
120
100

FLOOR and CEIL. The FLOOR function returns the largest integer equal to or less than the specified number.

The CEIL function returns the smallest integer equal to or greater than the specified number.

The following block and its output demonstrate these two functions:

BEGIN
DBMS_OUTPUT.put_line (FLOOR (1.5));
DBMS_OUTPUT.put_line (CEIL (1.5));
END;
/
1
2

MOD and REMAINDER. MOD and REMAINDER both return the remainder of one number divided by another, but that remainder is calculated differently for each function.

The formula used by Oracle Database for MOD is

MOD (m, n) = m - n * FLOOR (m/n)

when both m and n have the same sign (positive or negative). If the signs of m and n are different, then the formula used is:

MOD (m,n) = ( m - n * CEIL(m/n) )

whereas the formula used for REMAINDER is

n2 - (n1*N)

where n1 is not zero and where N is the integer nearest n2/n1. If n2/n1 equals x.5, then N is the nearest even integer.

Listing 4 includes a block that demonstrates the effect of and differences between these two functions.

Code Listing 4: Calls to MOD and REMAINDER

BEGIN
DBMS_OUTPUT.put_line (MOD (15, 4));
DBMS_OUTPUT.put_line (REMAINDER (15, 4));
DBMS_OUTPUT.put_line (MOD (15, 6));
DBMS_OUTPUT.put_line (REMAINDER (15, 6));
END;
/

And here is the output from this block:

3
-1
3
3

TO_CHAR. Use TO_CHAR to convert a number to a string. In its simplest form, you pass a single argument (the number) to TO_CHAR and it returns the string representation of that number, exactly long enough to contain all of its significant digits.

Listing 5 includes a block that shows some TO_CHAR examples. As you can see, leading and trailing zeros are not in the string representation of the number.

Code Listing 5: Calls to TO_CHAR

BEGIN
DBMS_OUTPUT.put_line (TO_CHAR (100.55));
DBMS_OUTPUT.put_line (TO_CHAR (000100.5500));
DBMS_OUTPUT.put_line (TO_CHAR (10000.00));
END;

And here is the output from this block:

100.55 100.55 10000

To specify a format for the string to which the number is converted, provide as the second argument to TO_CHAR a string that contains a combination of special format elements. Suppose, for example, that I want to display large numbers with a “1000s” delimiter. In other words, I want to display “10,000” instead of “10000” so I would use the following format: Often, when you have to convert a number to a string, you need that number to fit a certain format. You might, for example, want to display the number as a currency, so that even if there are no cents, you need to include the “.00”—in such cases, you will need to add a second argument in your call to TO_CHAR: the format mask.

BEGIN
DBMS_OUTPUT.put_line (
'Amount='||
TO_CHAR (
10000
, '9G999G999'));
END;

The G element indicates where in the string I would like to place the group separator. (The character used for the separator is determined by the National Language Settings database parameter NLS_NUMERIC_CHARACTERS.) The 9 element tells Oracle Database to put a significant digit or a blank space in that location. As a result, the output from this block is

Amount=    10,000

If I want to have zeros appear instead of blanks, I can use 0 instead of 9, as in

BEGIN
DBMS_OUTPUT.put_line (
'Amount=' ||
TO_CHAR (
10000
, '0G000G999'));
END;
Amount= 0,010,000

If I do not want any leading zeros, extra blanks, or white space appearing in my converted number, I will use the FM element, as in

BEGIN
DBMS_OUTPUT.put_line (
'Amount=' ||
TO_CHAR (
10000
, 'FM9G999G999'));
END;
Amount=10,000

Suppose that my number is actually a monetary unit consisting of dollars (or euros) and cents and I want to show the currency symbol as well as the cents portion. I can use the following format:

BEGIN
DBMS_OUTPUT.put_line (
'Salary=' ||
TO_CHAR (
14500.77
, 'FML999G999D99'));
END;
Salary=$14,500.77

The L element specifies the location of the local currency symbol (such as $ or €) in the return value (the NLS_CURRENCY parameter specifies the local currency symbol). The D element indicates the location of the decimal point. (The character used for the decimal point is specified by the database parameter NLS_NUMERIC_CHARACTERS.)

It is outside the scope of this article to explain all of the many elements available for use in number formats (there are, for example, at least four elements just for denoting monetary units). Check Oracle Database SQL Language Reference 11g Release 2 (11.2), for a complete description.

------------------------------

present  by  dylan.

Working with Numbers in PL/SQL(在PL/SQL中使用数字)的更多相关文章

  1. 用sql获取某字符串中的数字部分的语句

    create function dbo.F_Get_No ( @No varchar(100) ) RETURNS bigint AS BEGIN WHILE PATINDEX('%[^0-9]%', ...

  2. SQL函数:字符串中提取数字,英文,中文,过滤重复字符(转)

    --提取数字 IF OBJECT_ID('DBO.GET_NUMBER2') IS NOT NULL DROP FUNCTION DBO.GET_NUMBER2 GO )) ) AS BEGIN BE ...

  3. SQL with PL/SQL

    DDL commands --> create user / table / view / sequence alter DML --> data manipulation languag ...

  4. PL/SQL无法连接,提示:pl/sql initialization error sql*net not properly installed

    各种找资料都不行,最后还是在公司的线上环境中去找不同点配置好的.不多说了,就做了如下配置: 服务器环境是:windows server 2008 64位操作系统 1.电脑系统环境变量PATH增加:x: ...

  5. PL/SQL Developer执行.sql文件的几种方法

    1.复制SQL 第一种方法非常常见,也非常简单,先用文本编辑器打开.sql文件,然后把sql复制到PL/SQL Developer的SQL窗口或者命令窗口中运行就行了,本来我也是这么做的,但是我将SQ ...

  6. 七、dbms_rowid(用于在PL/SQL程序和SQL语句中取得行标识符)

    1.概述 作用:用于在PL/SQL程序和SQL语句中取得行标识符(rowid)的信息并建立ROWID,通过该包可以取得行所在的文件号,行所在文件的数据块号,行所在数据块的行号,以及数据库对象号等消息. ...

  7. SQL、PL/SQL、DDL、DML、TCL介绍

    SQL:结构化查询语言(Structured Query Language) PL/SQL:过程化SQL语言(Procedural Language/SQL) DDL(Data Definition ...

  8. Oracle PL/SQL 编程手册(SQL大全)

    一.SQLPLUS 1引言 SQL命令 以下17个是作为语句开头的关键字: alterdroprevoke auditgrantrollback* commit*inse ...

  9. SQL和PL/SQL的区别

    SQL和PL/SQL的区别 1. SQL是结构化查询语言,比较接近自然语言,使用SQL,只需要说干什么,不需要说怎么干.由数据定义语言.数据操纵语言.数据控制语言构成,它不面向过程,即前一条语句与后一 ...

  10. SQL语句、PL/SQL块和SQL*Plus命令之间的区别

    SQL语句.PL/SQL块和SQL*Plus命令之间的区别   原文链接:https://blog.csdn.net/liuzhushiqiang/article/details/12320941 在 ...

随机推荐

  1. 浅谈GitLab与Git

    前言:先解释下关于库的认识. Workspace:工作区 Index / Stage:暂存区 Repository:仓库区(或本地仓库) Remote:远程仓库 一.新增项目(远程仓库) 在GitLa ...

  2. python - XML文件及其操作

    xml文件也是实现不同语言或者程序之间进行数据交换的协议,它的特点是尖括号开头,尖括号结尾.使用范围就更为广泛了,tomcat resin kvm 等等,使用了大量的xml文件来进行相关配置.先来看一 ...

  3. iCIBA简单案例

    效果图: 代码: <!DOCTYPE html><html> <head> <meta charset="utf-8" /> < ...

  4. Sqlserver统计语句

    --查看被缓存的查询计划 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED st.text AS [SQL] , cp.cacheobjtype , c ...

  5. (转)关于font-size:100%

    重设浏览器默认字体大小 h1,h2,h3,h4,h5,h6 {font-size:100%;font-weight:normal;} 假如你设置body{font-size:12px;} 但h1是不会 ...

  6. Java ----------- SQL语句总结(更新中。。。。。。)

    #对数据库的操作 *创建数据库 CREATE DATABASE database_name:database_name为创建的数据库的变量名称. #对表的操作

  7. 关于DIPS的MVC 4.0项目发布与在IIS 7.0上的部署的方法

    本人技术笨拙,今天在发布DIPS的MVC4.0项目,并部署到IIS上,遇到各种问题.在查询相关资料后,最终得以解决,所以想把这个过程记录下来. 首先是MVC4.0项目的发布: 打开你的VS2012网站 ...

  8. .net 实现注册邮箱验证激活

    没事上网当了个注册邮箱验证激活的代码,用起来感觉还不错,特意和大家要一起分享一下 下面是主要实现代码: uing System.Net.Mail; public partial class jquer ...

  9. hdu 1282 回文数猜想

    Problem Description 一个正整数,如果从左向右读(称之为正序数)和从右向左读(称之为倒序数)是一样的,这样的数就叫回文数.任取一个正整数,如果不是回文数,将该数与他的倒序数相加,若其 ...

  10. C语言中的结构体和C++中的结构体以及C++中类的区别

    c++中结构体可以定义一个函数 C中的结构体和C++中结构体的不同之处:在C中的结构体只能自定义数据类型,结构体中不允许有函数,而C++中的结构体可以加入成员函数. C++中的结构体和类的异同: 一. ...