[置顶]C# 跨线程赋值的简单做法
posted @ 2012-01-19 15:27 Mayvar 阅读(1162) 评论(10) 编辑
posted @ 2012-01-19 15:27 Mayvar 阅读(1162) 评论(10) 编辑
posted @ 2012-04-12 09:48 Mayvar 阅读(101) 评论(0) 编辑
Oracle的分页查询语句
(一)分页查询格式:
SELECT * FROM
(SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
WHERE ROWNUM <= 40)
WHERE RN >= 21
其中最内层的查询SELECT * FROM TABLE_NAME表示不进行翻页的原始查询语句。ROWNUM <= 40和RN >= 21控制分页查询的每页的范围。
上面给出的这个分页查询语句,在大多数情况拥有较高的效率。分页的目的就是控制输出结果集大小,将结果尽快的返回。在上面的分页查询语句中,这种考虑主要体现在WHERE ROWNUM <= 40这句上。
选择第21到40条记录存在两种方法,一种是上面例子中展示的在查询的第二层通过ROWNUM <= 40来控制最大值,在查询的最外层控制最小值。而另一种方式是去掉查询第二层的WHERE ROWNUM <= 40语句,在查询的最外层控制分页的最小值和最大值。这是,查询语句如下:
SELECT * FROM
(SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A )WHERE RN BETWEEN 21 AND 40
对比这两种写法,绝大多数的情况下,第一个查询的效率比第二个高得多。
这是由于CBO优化模式下,Oracle可以将外层的查询条件推到内层查询中,以提高内层查询的执行效率。对于第一个查询语句,第二层的查询条件WHERE ROWNUM <= 40就可以被Oracle推入到内层查询中,这样Oracle查询的结果一旦超过了ROWNUM限制条件,就终止查询将结果返回了。
而第二个查询语句,由于查询条件BETWEEN 21 AND 40是存在于查询的第三层,而Oracle无法将第三层的查询条件推到最内层(即使推到最内层也没有意义,因为最内层查询不知道RN代表什么)。因此,对于第二个查询语句,Oracle最内层返回给中间层的是所有满足条件的数据,而中间层返回给最外层的也是所有数据。数据的过滤在最外层完成,显然这个效率要比第一个查询低得多。
上面分析的查询不仅仅是针对单表的简单查询,对于最内层查询是复杂的多表联合查询或最内层查询包含排序的情况一样有效。
这里就不对包含排序的查询进行说明了,下一篇文章会通过例子来详细说明。下面简单讨论一下多表联合的情况。对于最常见的等值表连接查询,CBO一般可能会采用两种连接方式NESTED LOOP和HASH JOIN(MERGE JOIN效率比HASH JOIN效率低,一般CBO不会考虑)。在这里,由于使用了分页,因此指定了一个返回的最大记录数,NESTED LOOP在返回记录数超过最大值时可以马上停止并将结果返回给中间层,而HASH JOIN必须处理完所有结果集(MERGE JOIN也是)。那么在大部分的情况下,对于分页查询选择NESTED LOOP作为查询的连接方法具有较高的效率(分页查询的时候绝大部分的情况是查询前几页的数据,越靠后面的页数访问几率越小)。
因此,如果不介意在系统中使用HINT的话,可以将分页的查询语句改写为:
SELECT /*+ FIRST_ROWS */ * FROM
(SELECT A.*, ROWNUM RN
FROM (SELECT * FROM TABLE_NAME) A
WHERE ROWNUM <= 40)
WHERE RN >= 21
(二)用几个例子来说明分页查询的效率。首先构造一个比较大的表作为测试表:
SQL> CREATE TABLE T AS SELECT * FROM DBA_OBJECTS, DBA_SEQUENCES;
表已创建。
SQL> SELECT COUNT(*) FROM T;
COUNT(*)
----------
457992
首先比较两种分页方法的区别:
SQL> SET AUTOT ON
SQL> COL OBJECT_NAME FORMAT A30
SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'T')
PL/SQL 过程已成功完成。
SQL> SELECT OBJECT_ID, OBJECT_NAME
2 FROM
3 (
4 SELECT ROWNUM RN, OBJECT_ID, OBJECT_NAME
5 FROM
6 (
7 SELECT OBJECT_ID, OBJECT_NAME FROM T
8 )
9 )
10 WHERE RN BETWEEN 11 AND 20;
OBJECT_ID OBJECT_NAME
---------- ------------------------------
5807 ALL_APPLY_PROGRESS
1769 ALL_ARGUMENTS
2085 ALL_ASSOCIATIONS
4997 ALL_AUDIT_POLICIES
4005 ALL_BASE_TABLE_MVIEWS
5753 ALL_CAPTURE
5757 ALL_CAPTURE_PARAMETERS
5761 ALL_CAPTURE_PREPARED_DATABASE
5765 ALL_CAPTURE_PREPARED_SCHEMAS
5769 ALL_CAPTURE_PREPARED_TABLES
已选择10行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=864 Card=457992 Bytes=42135264)
1 0 VIEW (Cost=864 Card=457992 Bytes=42135264)
2 1 COUNT
3 2 TABLE ACCESS (FULL) OF 'T' (Cost=864 Card=457992 Bytes=9617832)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
8979 consistent gets
7422 physical reads
0 redo size
758 bytes sent via SQL*Net to client
503 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10 rows processed
SQL> SELECT OBJECT_ID, OBJECT_NAME
2 FROM
3 (
4 SELECT ROWNUM RN, OBJECT_ID, OBJECT_NAME
5 FROM
6 (
7 SELECT OBJECT_ID, OBJECT_NAME FROM T
8 )
9 WHERE ROWNUM <= 20
10 )
11 WHERE RN >= 11;
OBJECT_ID OBJECT_NAME
---------- ------------------------------
5807 ALL_APPLY_PROGRESS
1769 ALL_ARGUMENTS
2085 ALL_ASSOCIATIONS
4997 ALL_AUDIT_POLICIES
4005 ALL_BASE_TABLE_MVIEWS
5753 ALL_CAPTURE
5757 ALL_CAPTURE_PARAMETERS
5761 ALL_CAPTURE_PREPARED_DATABASE
5765 ALL_CAPTURE_PREPARED_SCHEMAS
5769 ALL_CAPTURE_PREPARED_TABLES
已选择10行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=864 Card=20 Bytes=1840)
1 0 VIEW (Cost=864 Card=20 Bytes=1840)
2 1 COUNT (STOPKEY)
3 2 TABLE ACCESS (FULL) OF 'T' (Cost=864 Card=457992 Bytes=9617832)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
5 consistent gets
0 physical reads
0 redo size
758 bytes sent via SQL*Net to client
503 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10 rows processed
二者执行效率相差很大,一个需要8000多逻辑读,而另一个只需要5个逻辑读。观察二者的执行计划可以发现,两个执行计划唯一的区别就是第二个查询在COUNT这步使用了STOPKEY,也就是说,Oracle将ROWNUM <= 20推入到查询内层,当符合查询的条件的记录达到STOPKEY的值,则Oracle结束查询。
因此,可以预见,采用第二种方式,在翻页的开始部分查询速度很快,越到后面,效率越低,当翻到最后一页,效率应该和第一种方式接近。
SQL> SELECT OBJECT_ID, OBJECT_NAME
2 FROM
3 (
4 SELECT ROWNUM RN, OBJECT_ID, OBJECT_NAME
5 FROM
6 (
7 SELECT OBJECT_ID, OBJECT_NAME FROM T
8 )
9 WHERE ROWNUM <= 457990
10 )
11 WHERE RN >= 457980;
OBJECT_ID OBJECT_NAME
---------- ------------------------------
7128 XCF_I_HANDLE_STATUS
7126 XCF_P
7127 XCF_U1
7142 XDF
7145 XDF_I_DF_KEY
7146 XDF_I_HANDLE_STATUS
7143 XDF_P
7144 XDF_U1
TEST.YANGTINGKUN
TEST4.YANGTINGKUN
YANGTK.YANGTINGKUN
已选择11行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=864 Card=457990 Bytes=42135080)
1 0 VIEW (Cost=864 Card=457990 Bytes=42135080)
2 1 COUNT (STOPKEY)
3 2 TABLE ACCESS (FULL) OF 'T' (Cost=864 Card=457992 Bytes=9617832)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
8979 consistent gets
7423 physical reads
0 redo size
680 bytes sent via SQL*Net to client
503 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
11 rows processed
(三)
继续看查询的第二种情况,包含表连接的情况:
SQL> CREATE TABLE T AS SELECT * FROM DBA_USERS;
表已创建。
SQL> CREATE TABLE T1 AS SELECT * FROM DBA_SOURCE;
表已创建。
SQL> ALTER TABLE T ADD CONSTRAINT PK_T PRIMARY KEY (USERNAME);
表已更改。
SQL> ALTER TABLE T1 ADD CONSTRAINT FK_T1_OWNER FOREIGN KEY (OWNER)
2 REFERENCES T(USERNAME);
表已更改。
SQL> CREATE INDEX IND_T1_OWNER ON T1(NAME);
索引已创建。
SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'T')
PL/SQL 过程已成功完成。
SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'T1')
PL/SQL 过程已成功完成。
创建了T表和T1表,默认情况下,HASH JOIN的效率要比NESTED LOOP高很多:
SQL> SET AUTOT TRACE
SQL> SELECT * FROM T, T1 WHERE T.USERNAME = T1.OWNER;
已选择96985行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=844 Card=96985 Bytes=46164860)
1 0 HASH JOIN (Cost=844 Card=96985 Bytes=46164860)
2 1 TABLE ACCESS (FULL) OF 'T' (Cost=2 Card=12 Bytes=1044)
3 1 TABLE ACCESS (FULL) OF 'T1' (Cost=826 Card=96985 Bytes=37727165)
Statistics
----------------------------------------------------------
39 recursive calls
0 db block gets
14475 consistent gets
7279 physical reads
0 redo size
37565579 bytes sent via SQL*Net to client
71618 bytes received via SQL*Net from client
6467 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
96985 rows processed
SQL> SELECT /*+ FIRST_ROWS */ * FROM T, T1 WHERE T.USERNAME = T1.OWNER;
已选择96985行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: FIRST_ROWS (Cost=97811 Card=96985 Bytes=46164860)
1 0 NESTED LOOPS (Cost=97811 Card=96985 Bytes=46164860)
2 1 TABLE ACCESS (FULL) OF 'T1' (Cost=826 Card=96985 Bytes=37727165)
3 1 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=1 Card=1 Bytes=87)
4 3 INDEX (UNIQUE SCAN) OF 'PK_T' (UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
117917 consistent gets
7268 physical reads
0 redo size
37565579 bytes sent via SQL*Net to client
71618 bytes received via SQL*Net from client
6467 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
96985 rows processed
但是如果分页查询的内层是这种连接查询的话,使用NESTED LOOP可以更快的得到前N条记录。
下面看一下这种情况下的分页查询情况:
SQL> SELECT USER_ID, USERNAME, NAME
2 FROM
3 (
4 SELECT ROWNUM RN, USER_ID, USERNAME, NAME
5 FROM
6 (
7 SELECT T.USER_ID, T.USERNAME, T1.NAME
8 FROM T, T1
9 WHERE T.USERNAME = T1.OWNER
10 )
11 WHERE ROWNUM <= 20
12 )
13 WHERE RN >= 11;
已选择10行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=830 Card=20 Bytes=1200)
1 0 VIEW (Cost=830 Card=20 Bytes=1200)
2 1 COUNT (STOPKEY)
3 2 HASH JOIN (Cost=830 Card=96985 Bytes=2909550)
4 3 TABLE ACCESS (FULL) OF 'T' (Cost=2 Card=12 Bytes=132)
5 3 TABLE ACCESS (FULL) OF 'T1' (Cost=826 Card=96985 Bytes=1842715)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
8 consistent gets
7 physical reads
0 redo size
574 bytes sent via SQL*Net to client
503 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10 rows processed
SQL> SELECT /*+ FIRST_ROWS */ USER_ID, USERNAME, NAME
2 FROM
3 (
4 SELECT ROWNUM RN, USER_ID, USERNAME, NAME
5 FROM
6 (
7 SELECT T.USER_ID, T.USERNAME, T1.NAME
8 FROM T, T1
9 WHERE T.USERNAME = T1.OWNER
10 )
11 WHERE ROWNUM <= 20
12 )
13 WHERE RN >= 11;
已选择10行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: FIRST_ROWS (Cost=97811 Card=20 Bytes=1200)
1 0 VIEW (Cost=97811 Card=20 Bytes=1200)
2 1 COUNT (STOPKEY)
3 2 NESTED LOOPS (Cost=97811 Card=96985 Bytes=2909550)
4 3 TABLE ACCESS (FULL) OF 'T1' (Cost=826 Card=96985 Bytes=1842715)
5 3 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=1 Card=1 Bytes=11)
6 5 INDEX (UNIQUE SCAN) OF 'PK_T' (UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
28 consistent gets
0 physical reads
0 redo size
574 bytes sent via SQL*Net to client
503 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10 rows processed
看上去似乎HASH JOIN效率更高,难道上面说错了。
其实这个现象是由于这个例子的特殊性造成的。T表是根据DBA_USERS创建,这张表很小。HASH JOIN中第一步也就是第一张表的全表扫描是无法应用STOPKEY的,这就是上面提到的NESTED LOOP比HASH JOIN优势的地方。但是,这个例子中,恰好第一张表很小,对这张表的全扫描的代价极低,因此,显得HASH JOIN效率更高。但是,这不具备共性,如果两张表的大小相近,或者Oracle错误的选择了先扫描大表,则使用HASH JOIN的效率就会低得多。
SQL> SELECT USER_ID, USERNAME, NAME
2 FROM
3 (
4 SELECT ROWNUM RN, USER_ID, USERNAME, NAME
5 FROM
6 (
7 SELECT /*+ ORDERED */ T.USER_ID, T.USERNAME, T1.NAME
8 FROM T1, T
9 WHERE T.USERNAME = T1.OWNER
10 )
11 WHERE ROWNUM <= 20
12 )
13 WHERE RN >= 11;
已选择10行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=951 Card=20 Bytes=1200)
1 0 VIEW (Cost=951 Card=20 Bytes=1200)
2 1 COUNT (STOPKEY)
3 2 HASH JOIN (Cost=951 Card=96985 Bytes=2909550)
4 3 TABLE ACCESS (FULL) OF 'T1' (Cost=826 Card=96985 Bytes=1842715)
5 3 TABLE ACCESS (FULL) OF 'T' (Cost=2 Card=12 Bytes=132)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
8585 consistent gets
7310 physical reads
0 redo size
601 bytes sent via SQL*Net to client
503 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10 rows processed
通过HINT提示,让Oracle先扫描大表,这回结果就很明显了。NESTED LOOP的效果要比HASH JOIN好得多。
下面,继续比较一下两个分页操作的写法,为了使结果更具有代表性,这里都采用了FIRST_ROWS提示,让Oracle采用NESTED LOOP的方式来进行表连接:
SQL> SELECT /*+ FIRST_ROWS */ USER_ID, USERNAME, NAME
2 FROM
3 (
4 SELECT ROWNUM RN, USER_ID, USERNAME, NAME
5 FROM
6 (
7 SELECT T.USER_ID, T.USERNAME, T1.NAME
8 FROM T, T1
9 WHERE T.USERNAME = T1.OWNER
10 )
11 WHERE ROWNUM <= 20
12 )
13 WHERE RN >= 11;
已选择10行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: FIRST_ROWS (Cost=97811 Card=20 Bytes=1200)
1 0 VIEW (Cost=97811 Card=20 Bytes=1200)
2 1 COUNT (STOPKEY)
3 2 NESTED LOOPS (Cost=97811 Card=96985 Bytes=2909550)
4 3 TABLE ACCESS (FULL) OF 'T1' (Cost=826 Card=96985 Bytes=1842715)
5 3 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=1 Card=1 Bytes=11)
6 5 INDEX (UNIQUE SCAN) OF 'PK_T' (UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
28 consistent gets
0 physical reads
0 redo size
574 bytes sent via SQL*Net to client
503 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10 rows processed
SQL> SELECT /*+ FIRST_ROWS */ USER_ID, USERNAME, NAME
2 FROM
3 (
4 SELECT ROWNUM RN, USER_ID, USERNAME, NAME
5 FROM
6 (
7 SELECT T.USER_ID, T.USERNAME, T1.NAME
8 FROM T, T1
9 WHERE T.USERNAME = T1.OWNER
10 )
11 )
12 WHERE RN BETWEEN 11 AND 20;
已选择10行。
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: FIRST_ROWS (Cost=97811 Card=96985 Bytes=5819100)
1 0 VIEW (Cost=97811 Card=96985 Bytes=5819100)
2 1 COUNT
3 2 NESTED LOOPS (Cost=97811 Card=96985 Bytes=2909550)
4 3 TABLE ACCESS (FULL) OF 'T1' (Cost=826 Card=96985 Bytes=1842715)
5 3 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=1 Card=1 Bytes=11)
6 5 INDEX (UNIQUE SCAN) OF 'PK_T' (UNIQUE)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
105571 consistent gets
7299 physical reads
0 redo size
574 bytes sent via SQL*Net to client
503 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
10 rows processed
两种写法的效率差别极大。关键仍然是是否能将STOPKEY应用到最内层查询中。
对于表连接来说,在写分页查询的时候,可以考虑增加FIRST_ROWS提示,它有助于更快的将查询结果返回。
其实,不光是表连接,对于所有的分页查询都可以加上FIRST_ROWS提示。不过需要注意的时,分页查询的目标是尽快的返回前N条记录,因此,无论是ROWNUM还是FIRST_ROWS机制都是提高前几页的查询速度,对于分页查询的最后几页,采用这些机制不但无法提高查询速度,反而会明显降低查询效率,对于这一点使用者应该做到心中有数。
posted @ 2012-04-11 16:01 Mayvar 阅读(52) 评论(0) 编辑
这个基础问题,您可以选对么,如下:
我创建了如下包头:
CREATE OR REPLACE PACKAGE plch_pkg
AUTHID DEFINER
IS
TYPE names_t IS TABLE OF VARCHAR2 (20)
INDEX BY PLS_INTEGER;
END plch_pkg;
/
哪些选项在执行之后会显示"3"?
(A)
DECLARE
l_names CONSTANT plch_pkg.names_t
:= plch_pkg.names_t ('Horton', 'Hears', 'A Who') ;
BEGIN
DBMS_OUTPUT.put_line (l_names.COUNT);
END;
/
(B)
DECLARE
l_names CONSTANT plch_pkg.names_t
:= plch_pkg.names_t () ;
BEGIN
l_names (1) := 'Horton';
l_names (2) := 'Hears';
l_names (3) := 'A Who';
DBMS_OUTPUT.put_line (l_names.COUNT);
END;
/
(C)
CREATE OR REPLACE FUNCTION plch_dr_seuss_names
RETURN plch_pkg.names_t
IS
l_return plch_pkg.names_t;
BEGIN
l_return (1) := 'Horton';
l_return (2) := 'Hears';
l_return (3) := 'A Who';
RETURN l_return;
END plch_dr_seuss_names;
/
DECLARE
l_names CONSTANT plch_pkg.names_t
:= plch_dr_seuss_names () ;
BEGIN
DBMS_OUTPUT.put_line (l_names.COUNT);
END;
/
(D)
CREATE OR REPLACE FUNCTION plch_dr_seuss_names (
name1_in IN VARCHAR2
, name2_in IN VARCHAR2
, name3_in IN VARCHAR2)
RETURN plch_pkg.names_t
IS
l_return plch_pkg.names_t;
BEGIN
l_return (1) := name1_in;
l_return (2) := name2_in;
l_return (3) := name3_in;
RETURN l_return;
END plch_dr_seuss_names;
/
DECLARE
l_names CONSTANT plch_pkg.names_t
:= plch_dr_seuss_names ('Horton', 'Hears', 'A Who') ;
BEGIN
DBMS_OUTPUT.put_line (l_names.COUNT);
END;
答案:CD
解释:ORACLE只对嵌套表(NESTED TABLE)和可变数组(VARRAY)提供构造函数(constructor function), ASSOCIATED ARRAY (即INDEX BY表)则没有这个构造函数,必须采用自定义函数。常量在声明的部分必须赋值,不能够在块中赋值。
posted @ 2012-04-07 09:06 Mayvar 阅读(680) 评论(0) 编辑
这里主要说明 [,]与[][] 之间的区别:
int[,] a = {{ 1, 3 },{2,0},{2,6}};
/*int[,] b = { { 1, 3,2 }, { 2, 0 }, { 2, 6 } };*/
MessageBox.Show(a[0,0].ToString());
int[][] arr = new int[3][] { new int[] { 1, 2 }, new int[] { 1, 2, 3 }, new int[] { 1, 2, 3 } };
/*int[][] arr2 = new int[3][];
arr2[0][1] = 1;
arr2[0][2] = 2;
MessageBox.Show((arr2[0][0]).ToString());*/
MessageBox.Show((arr[0][1]).ToString());
容易出现的错误:
[,]中,a必须是对称的;b 就是错误的。
[][]中,必须要new新的对象,否则出错;
arr2就没有初始化里面的单个数组,所以是错误的!
posted @ 2012-03-31 17:05 Mayvar 阅读(486) 评论(0) 编辑
.NET Framework 提供了可自定义的、适于常规用途的格式化机制,可将值转换为适合显示的字符串。例如,可以将数值格式化为十六进制、科学记数法或者由用户指定的标点符号分隔成组的一系列数字。可以将日期和时间格式化为适合于特定的国家、地区或区域性。可以将枚举常量格式化为它的数值或名称。
您可以通过指定格式字符串和格式提供程序或使用默认设置来控制格式化。格式字符串包含一个或多个格式说明符字符,以指示如何转换值。格式提供程序提供了转换特定类型所需的其他控制、替换和区域性等方面的信息。
您可以通过实现 IFormattable 接口来重写 .NET Framework 解释格式化字符串的方法;通过实现 IFormatProvider 接口来提供您自己的格式提供程序;通过实现 ICustomFormatter 接口来执行您自己的格式化。
.NET Framework 提供了名为复合格式化的功能,它使用一个或多个格式字符串将一个或多个格式化值嵌入输出字符串。输出字符串可用于进行进一步处理,显示到系统控制台或者写入到流。
格式说明符
.NET Framework 定义了标准和自定义格式说明符,用于格式化数字、日期和时间以及枚举。各种格式化输出字符串的方法(例如 Console.WriteLine 和所有类型的 ToString 方法),以及一些分析输入字符串的方法(例如 DateTime.ParseExact)都使用格式化说明符。
有关格式化数字数据的信息,请参见“数字格式字符串”。有关常用的数字格式说明符的列表,请参见“标准数字格式字符串”;有关自定义格式说明符(可用于创建自己的格式字符串)的列表,请参见“自定义数字格式字符串”。
关于格式化日期和时间的信息,请参见“日期与时间格式字符串”。有关常用日期和时间格式说明符的列表,请参见“标准 DateTime 格式字符串”;有关自定义时间和日期格式说明符(可用于创建自己的格式字符串)的列表,请参见“自定义 DateTime 格式字符串”。
有关格式化枚举的信息,以及标准枚举格式说明符的列表,请参见“枚举格式字符串”。
分析和格式说明符
格式化将类型的值转化为字符串表示形式;分析则与格式化相反,它是从字符串表示形式创建数据类型。格式提供程序控制如何执行分析,一些方法(例如 DateTime.ParseExact)采用格式说明符参数,可指示字符串表示形式的预期格式。有关分析的更多信息,请参见“分析字符串”。
ToString 和格式说明符
.NET Framework 支持重载类型的默认 ToString 方法,该方法执行基本格式化,版本为 ToString 的专用版本,此版本使用格式说明符参数来指示如何格式化值。有关更多信息,请参见“格式化基类型”和 IFormattable 接口。
Format 函数返回根据格式 String 表达式中包含的指令设置格式的字符串。
1.
<%@ Page Language="C#" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
string a = "Clingingboy";
Response.Write(string.Format("你的姓名是:{0}",a));//{0}表示占位符,传递给第二个参数来替换该占位符
string name = "Clingingboy";
string age = "20";
string city = "hangzhou";
Response.Write("<br>");
Response.Write(string.Format("我的姓名是{1},年龄是{0},来自{2}",age,name,city));
Response.Write(string.Format("<pre>{0,20}</pre>", "111"));//占位符宽度
}
</script>
2.格式化数值
<%@ Page Language="C#" %>
<script language="C#" runat=server>
void Page_Load(Object sender , EventArgs e)
{
int intNum;
Decimal decNum;
intNum = 32001;
decNum = 32001.9099m;
// Decimal Format;
Response.Write( intNum.ToString( "d" ) + "<BR>" );
// => Displays 32001
// Exponential Format
Response.Write( intNum.ToString( "e" )+ "<BR>" );
// => Displays 3.200100e+004
Response.Write( decNum.ToString( "e" )+ "<BR>" );
// => Displays 3.200191e+004
// Fixed-Point Format
Response.Write( intNum.ToString( "f" ) + "<BR>");
// => Displays 32001.00
Response.Write( decNum.ToString( "f" ) + "<BR>");
// => Displays 32001.91
// General Format
Response.Write( intNum.ToString( "g" )+ "<BR>" );
// => Displays 32001
Response.Write( decNum.ToString( "g" )+ "<BR>" );
// => Displays 32001.9099
// Number Format
Response.Write( intNum.ToString( "n" )+ "<BR>" );
// => Displays 32,001.00
Response.Write( decNum.ToString( "n" )+ "<BR>" );
// => Displays 32,001.91
Response.Write(intNum.ToString("x") + "<BR>");
//7d01
}
</script>
使用Format来格式化
Response.Write(string.Format("{0:n}", 123456) + "<BR>");
<%@ Page Language="C#" %>
<script language="C#" runat=server>
void Page_Load(Object sender , EventArgs e)
{
int intNum;
Decimal decNum;
intNum = 32001;
decNum = 32001.9099m;
// Decimal Format;
Response.Write(string.Format("{0:n}", 123456) + "<BR>");//0为索引值,n为格式化
Response.Write( intNum.ToString( "d10" ) + "<BR>" );//在数值前面加0,总位数为10
Response.Write(intNum.ToString("n10") + "<BR>");//小数位数
}
</script>
3.格式化货币
<%@ Page Language="C#" %>
<script language="C#" runat=server>
void Page_Load(Object sender , EventArgs e)
{
decimal intNum;
intNum = 32001.4633m;
// Decimal Format;
Response.Write(string.Format("{0:c}", intNum) + "<BR>");//0为索引值,n为格式化
Response.Write(string.Format("{0:c3}", intNum) + "<BR>");
Response.Write(intNum.ToString("c") + "<BR>");//默认小数位数位为2
Response.Write( intNum.ToString( "c1" ) + "<BR>" );//自动四舍五入
}
</script>
4.格式化日期和时间
<%@ Page Language="C#" %>
<body style="font-family: 宋体; font-size: 12px; color: sandybrown;">
</body>
<script language="C#" runat=server>
void Page_Load(Object sender , EventArgs e)
{
DateTime dtmDate;
dtmDate = DateTime.Now;
// short Date
Response.Write( dtmDate.ToString( "d" ) );
Response.Write("<br>" );
// => Displays 2/13/2001
// long Date
Response.Write( dtmDate.ToString( "D" ) );
Response.Write("<br>" );
// => Displays Tuesday, February 13, 2001
// long Date and short Time
Response.Write( dtmDate.ToString( "f" ) );
Response.Write("<br>" );
// => Displays Tuesday, February 13, 2001 3:40 PM
// long Date and long Time
Response.Write( dtmDate.ToString( "F" ) );
Response.Write("<br>" );
// => Displays Tuesday, February 13, 2001 3:41:04 PM
// short Date and short Time
Response.Write( dtmDate.ToString( "g" ) );
Response.Write("<br>" );
// => Displays 2/13/2001 3:42 PM
// short Date and long Time
Response.Write( dtmDate.ToString( "G" ) );
Response.Write("<br>" );
// => Displays 2/13/2001 3:42:52 PM
// Month and Day
Response.Write( dtmDate.ToString( "M" ) );
Response.Write("<br>" );
// => Displays February 13
// RFC 1123
Response.Write( dtmDate.ToString( "R" ) );
Response.Write("<br>" );
// => Displays Tue, 13 Feb 2001 15:44:52 GMT
// ISO 8601
Response.Write( dtmDate.ToString( "s" ) );
Response.Write("<br>" );
// => Displays 2001-02-13T15:45:55
// short Time
Response.Write( dtmDate.ToString( "t" ) );
Response.Write("<br>" );
// => Displays 3:47 PM
// long Time
Response.Write( dtmDate.ToString( "T" ) );
Response.Write("<br>" );
// => Displays 3:47:37 PM
// Universal ISO 8601
Response.Write( dtmDate.ToString( "u" ) );
Response.Write("<br>" );
// => Displays 2001-02-13 15:48:41Z
// Universal Time
Response.Write( dtmDate.ToString( "U" ) );
Response.Write("<br>" );
// => Displays Tuesday, February 13, 2001 11:49:51 PM
// Month and Year
Response.Write( dtmDate.ToString( "Y" ) );
Response.Write("<br>" );
// => Displays February, 2001
}
</script>
posted @ 2012-03-30 13:40 Mayvar 阅读(8) 评论(0) 编辑
posted @ 2012-03-19 15:14 Mayvar 阅读(650) 评论(0) 编辑
posted @ 2012-03-15 13:02 Mayvar 阅读(12) 评论(0) 编辑
posted @ 2012-03-10 19:50 Mayvar 阅读(23) 评论(0) 编辑
posted @ 2012-02-24 10:33 Mayvar 阅读(3) 评论(0) 编辑
posted @ 2012-02-24 10:03 Mayvar 阅读(2) 评论(0) 编辑