個人檔案东海青蛙部落格 工具 說明
10月7日

如何实现行列转换

<1>、固定列数的行列转换

student subject grade
---------------------------
student1 语文 80
student1 数学 70
student1 英语 60
student2 语文 90
student2 数学 80
student2 英语 100
...
转换为
语文 数学 英语
student1 80 70 60
student2 90 80 100
...
语句如下:
select student,sum(decode(subject,'语文', grade,null)) "语文",
sum(decode(subject,'数学', grade,null)) "数学",
sum(decode(subject,'英语', grade,null)) "英语"
from table
group by student

<2>、不定列行列转换

c1 c2
--------------
1 我
1 是
1 谁
2 知
2 道
3 不
...
转换为
1 我是谁
2 知道
3 不

这一类型的转换必须借助于PL/SQL来完成,这里给一个例子
CREATE OR REPLACE FUNCTION get_c2(tmp_c1 NUMBER)
RETURN VARCHAR2
IS
Col_c2 VARCHAR2(4000);
BEGIN
FOR cur IN (SELECT c2 FROM t WHERE c1=tmp_c1) LOOP
Col_c2 := Col_c2||cur.c2;
END LOOP;
Col_c2 := rtrim(Col_c2,1);
RETURN Col_c2;
END;
/
SQL> select distinct c1 ,get_c2(c1) cc2 from table;即可


--例子:
create table okcai_1
(
user_id varchar2(10),
user_number varchar2(10),
user_num number(8)
)
user_id user_number user_num
---------------------
1 123  2
1 456  5
1 789  6
2 11   2
2 22   3
2 33   4
2 44   5
2 55   6
2 66   7
2 77   8
3 1234 1
3 5678 2

方式一:
create or replace function get_col(
       p_userId number,
       p_col    number
) return varchar
as
v_tmp varchar2(255);
begin
     select user_number||chr(9)||user_num into v_tmp
     from
     (select user_number,user_num,rownum row_id
      from okcai_1
      where user_id = p_userId) a
     where row_id = p_col;
     return ltrim(v_tmp);
     --return v_tmp;
end;

然后
select distinct user_id,get_col(user_id,1),get_col(user_id,2),get_col(user_id,3) .... from okcai_1

方式二:
create or replace function get_col(
       p_userId number,
       p_col    number
) return varchar
as
v_tmp varchar2(255);
begin
     select user_number||chr(9)||user_num into v_tmp
     from
     (select user_number,user_num,rownum row_id
      from okcai_1
      where user_id = p_userId) a
     where row_id = p_col;
     return ltrim(v_tmp);
     --return v_tmp;
end;
select distinct user_id,get_col_new(user_id) from okcai_1;

Oracle 游标使用大全3

游标FOR循环 

在大多数时候我们在设计程序的时候都遵循下面的步骤: 

1、打开游标 

2、开始循环 

3、从游标中取值 

4、检查那一行被返回 

5、处理 

6、关闭循环 

7、关闭游标 

    可以简单的把这一类代码称为游标用于循环。但还有一种循环与这种类型不相同,这就是FOR循环,用于FOR循环的游标按照正常的声明方式声明,它的优点在于不需要显式的打开、关闭、取数据,测试数据的存在、定义存放数据的变量等等。游标FOR循环的语法如下: 

 

FOR record_name IN 

 (corsor_name[(parameter[,parameter]...)] 

 | (query_difinition) 

LOOP 

  statements 

END LOOP; 

 

下面我们用for循环重写上面的例子: 

DECALRE 

CURSOR c_dept IS SELECT deptno,dname FROM dept ORDER BY deptno; 

CURSOR c_emp (p_dept VARACHAR2) IS 

 SELECT ename,salary 

 FROM emp 

 WHERE deptno=p_dept 

 ORDER BY ename 

v_tot_salary EMP.SALARY%TYPE; 

BEGIN 

   FOR r_dept IN c_dept LOOP 

     DBMS_OUTPUT.PUT_LINE('Department:'|| r_dept.deptno||'-'||r_dept.dname); 

     v_tot_salary:=0; 

     FOR r_emp IN c_emp(r_dept.deptno) LOOP 

    DBMS_OUTPUT.PUT_LINE('Name:' || v_ename || 'salary:' || v_salary);  

    v_tot_salary:=v_tot_salary+v_salary; 

     END LOOP; 

     DBMS_OUTPUT.PUT_LINE('Toltal Salary for dept:'|| v_tot_salary); 

  END LOOP; 

END; 

 

在游标FOR循环中使用查询 

    在游标FOR循环中可以定义查询,由于没有显式声明所以游标没有名字,记录名通过游标查询来定义。 

DECALRE 

 v_tot_salary EMP.SALARY%TYPE; 

BEGIN 

  FOR r_dept IN (SELECT deptno,dname FROM dept ORDER BY deptno) LOOP 

     DBMS_OUTPUT.PUT_LINE('Department:'|| r_dept.deptno||'-'||r_dept.dname); 

     v_tot_salary:=0; 

     FOR r_emp IN (SELECT ename,salary 

               FROM emp 

               WHERE deptno=p_dept 

               ORDER BY ename) LOOP 

       DBMS_OUTPUT.PUT_LINE('Name:'|| v_ename||' salary:'||v_salary); 

       v_tot_salary:=v_tot_salary+v_salary; 

     END LOOP; 

  DBMS_OUTPUT.PUT_LINE('Toltal Salary for dept:'|| v_tot_salary); 

  END LOOP; 

END; 

 

游标中的子查询 

    语法如下: 

    

CURSOR C1 IS SELECT * FROM emp 

  WHERE deptno NOT IN (SELECT deptno 

   FROM dept 

   WHERE dname!='ACCOUNTING'); 

可以看出与SQL中的子查询没有什么区别。 

 

游标中的更新和删除 

    PL/SQL中依然可以使用UPDATEDELETE语句更新或删除数据行。显式游标只有在需要获得多行数据的情况下使用。PL/SQL提供了仅仅使用游标就可以执行删除或更新记录的方法。 

UPDATEDELETE语句中的WHERE CURRENT OF子串专门处理要执行UPDATEDELETE操作的表中取出的最近的数据。要使用这个方法,在声明游标时必须使用FOR UPDATE子串,当对话使用FOR UPDATE子串打开一个游标时,所有返回集中的数据行都将处于行级(ROW-LEVEL)独占式锁定,其他对象只能查询这些数据行,不能进行UPDATEDELETESELECT...FOR            UPDATE操作。 

 

语法: 

    FOR UPDATE [OF [schema.]table.column[,[schema.]table.column].. 

    [nowait] 

    

    在多表查询中,使用OF子句来锁定特定的表,如果忽略了OF子句,那么所有表中选择的数据行都将被锁定。如果这些数据行已经被其他会话锁定,那么正常情况下ORACLE将等待,直到数据行解锁。 

 

UPDATEDELETE中使用WHERE CURRENT OF子串的语法如下: 

 

WHERE{CURRENT OF cursor_name|search_condition} 

 

例: 

DELCARE 

CURSOR c1 IS SELECT empno,salary 

 FROM emp 

 WHERE comm IS NULL 

 FOR UPDATE OF comm; 

v_comm NUMBER(10,2); 

BEGIN 

   FOR r1 IN c1 LOOP 

     IF r1.salary<500 THEN 

       v_comm:=r1.salary*0.25; 

     ELSEIF r1.salary<1000 THEN 

       v_comm:=r1.salary*0.20; 

     ELSEIF r1.salary<3000 THEN 

       v_comm:=r1.salary*0.15; 

     ELSE 

         v_comm:=r1.salary*0.12; 

     END IF; 

   UPDATE emp; 

   SET comm=v_comm 

   WHERE CURRENT OF c1l; 

   END LOOP; 

END

Oracle 游标使用大全2

使用游标 

    这里要做一个声明,我们所说的游标通常是指显式游标,因此从现在起没有特别指明的情况,我们所说的游标都是指显式游标。要在程序中使用游标,必须首先声明游标。 

 

声明游标 

语法: 

    CURSOR cursor_name IS select_statement; 

 

PL/SQL中游标名是一个未声明变量,不能给游标名赋值或用于表达式中。 

 

例: 

    DELCARE 

    CURSOR C_EMP IS SELECT empno,ename,salary 

    FROM emp 

    WHERE salary>2000 

    ORDER BY ename; 

    ........ 

    BEGIN 

    在游标定义中SELECT语句中不一定非要表可以是视图,也可以从多个表或视图中选择的列,甚至可以使用*来选择所有的列  

    

打开游标 

使用游标中的值之前应该首先打开游标,打开游标初始化查询处理。打开游标的语法是: 

    OPEN cursor_name 

       cursor_name是在声明部分定义的游标名。 

    

例: 

     OPEN C_EMP; 

        

关闭游标 

语法: 

     CLOSE cursor_name 

    

例: 

     CLOSE C_EMP; 

 

从游标提取数据 

    从游标得到一行数据使用FETCH命令。每一次提取数据后,游标都指向结果集的下一行。语法如下: 

     FETCH cursor_name INTO variable[,variable,...] 

     对于SELECT定义的游标的每一列,FETCH变量列表都应该有一个变量与之相对应,变量的类型也要相同。 

 

例: 

   SET SERVERIUTPUT ON 

   DECLARE 

     v_ename EMP.ENAME%TYPE; 

     v_salary EMP.SALARY%TYPE; 

     CURSOR c_emp IS SELECT ename,salary FROM emp; 

     BEGIN 

       OPEN c_emp; 

          FETCH c_emp INTO v_ename,v_salary; 

            DBMS_OUTPUT.PUT_LINE('Salary of Employee'|| v_ename ||'is'|| v_salary); 

          FETCH c_emp INTO v_ename,v_salary; 

            DBMS_OUTPUT.PUT_LINE('Salary of Employee'|| v_ename ||'is'|| v_salary); 

          FETCH c_emp INTO v_ename,v_salary; 

            DBMS_OUTPUT.PUT_LINE('Salary of Employee'|| v_ename ||'is'|| v_salary); 

       CLOSE c_emp; 

     END 

     

    这段代码无疑是非常麻烦的,如果有多行返回结果,可以使用循环并用游标属性为结束循环的条件,以这种方式提取数据,程序的可读性和简洁性都大为提高,下面我们使用循环重新写上面的程序: 

SET SERVERIUTPUT ON 

DECLARE 

v_ename EMP.ENAME%TYPE; 

v_salary EMP.SALARY%TYPE; 

CURSOR c_emp IS SELECT ename,salary FROM emp;  

BEGIN 

  OPEN c_emp; 

    LOOP 

      FETCH c_emp INTO v_ename,v_salary; 

      EXIT WHEN c_emp%NOTFOUND; 

      DBMS_OUTPUT.PUT_LINE('Salary of Employee'|| v_ename ||'is'|| v_salary); 

END 

 

记录变量 

    定义一个记录变量使用TYPE命令和%ROWTYPE,关于%ROWsTYPE的更多信息请参阅相关资料。 

    记录变量用于从游标中提取数据行,当游标选择很多列的时候,那么使用记录比为每列声明一个变量要方便得多。 

    当在表上使用%ROWTYPE并将从游标中取出的值放入记录中时,如果要选择表中所有列,那么在SELECT子句中使用*比将所有列名列出来要安全得多。 

 

例: 

SET SERVERIUTPUT ON 

DECLARE 

R_emp EMP%ROWTYPE; 

CURSOR c_emp IS SELECT * FROM emp; 

BEGIN 

  OPEN c_emp; 

   LOOP 

     FETCH c_emp INTO r_emp; 

     EXIT WHEN c_emp%NOTFOUND; 

     DBMS_OUT.PUT.PUT_LINE('Salary of Employee'||r_emp.ename||'is'|| r_emp.salary); 

   END LOOP; 

  CLOSE c_emp; 

END; 

 

%ROWTYPE也可以用游标名来定义,这样的话就必须要首先声明游标: 

 

SET SERVERIUTPUT ON 

DECLARE 

CURSOR c_emp IS SELECT ename,salary FROM emp; 

R_emp c_emp%ROWTYPE; 

BEGIN 

 OPEN c_emp; 

  LOOP 

    FETCH c_emp INTO r_emp; 

    EXIT WHEN c_emp%NOTFOUND; 

    DBMS_OUT.PUT.PUT_LINE('Salary of Employee'||r_emp.ename||'is'|| r_emp.salary); 

  END LOOP; 

 CLOSE c_emp; 

END; 

 

带参数的游标 

    与存储过程和函数相似,可以将参数传递给游标并在查询中使用。这对于处理在某种条件下打开游标的情况非常有用。它的语法如下: 

 

CURSOR cursor_name[(parameter[,parameter],...)] IS select_statement; 

 

定义参数的语法如下: 

   Parameter_name [IN] data_type[{:=|DEFAULT} value] 

 

  与存储过程不同的是,游标只能接受传递的值,而不能返回值。参数只定义数据类型,没有大小。 

   另外可以给参数设定一个缺省值,当没有参数值传递给游标时,就使用缺省值。游标中定义的参数只是一个占位符,在别处引用该参数不一定可靠。 

 

在打开游标时给参数赋值,语法如下: 

 

OPEN cursor_name[value[,value]....]; 

参数值可以是文字或变量。 

 

例: 

DECALRE 

CURSOR c_dept IS SELECT * FROM dept ORDER BY deptno; 

CURSOR c_emp (p_dept VARACHAR2) IS 

  SELECT ename,salary 

  FROM emp 

  WHERE deptno=p_dept 

  ORDER BY ename 

r_dept DEPT%ROWTYPE; 

v_ename EMP.ENAME%TYPE; 

v_salary EMP.SALARY%TYPE; 

v_tot_salary EMP.SALARY%TYPE; 

BEGIN 

  OPEN c_dept; 

     LOOP 

        FETCH c_dept INTO r_dept; 

        EXIT WHEN c_dept%NOTFOUND; 

        DBMS_OUTPUT.PUT_LINE('Department:'|| r_dept.deptno||'-'||r_dept.dname); 

        v_tot_salary:=0; 

        OPEN c_emp(r_dept.deptno); 

            LOOP 

               FETCH c_emp INTO v_ename,v_salary; 

               EXIT WHEN c_emp%NOTFOUND; 

               DBMS_OUTPUT.PUT_LINE('Name:'|| v_ename||' salary:'||v_salary); 

               v_tot_salary:=v_tot_salary+v_salary; 

            END LOOP; 

        CLOSE c_emp; 

        DBMS_OUTPUT.PUT_LINE('Toltal Salary for dept:'|| v_tot_salary); 

     END LOOP; 

  CLOSE c_dept; 

END; 

 

Oracle 游标使用大全1

查询 

    SELECT语句用于从数据库中查询数据,当在PL/SQL中使用SELECT语句时,要与INTO子句一起使用,查询的返回值被赋予INTO子句中的变量,变量的声明是在DELCARE中。SELECT             INTO语法如下: 

     SELECT [DISTICT|ALL]{*|column[,column,...]} 

     INTO (variable[,variable,...] |record) 

     FROM {table|(sub-query)}[alias] 

     WHERE............ 

    PL/SQLSELECT语句只返回一行数据。如果超过一行数据,那么就要使用显式游标(对游标的讨论我们将在后面进行),INTO子句中要有与SELECT子句中相同列数量的变量。INTO子句中也可以是记录变量。 

 

%TYPE属性 

     PL/SQL中可以将变量和常量声明为内建或用户定义的数据类型,以引用一个列名,同时继承他的数据类型和大小。这种动态赋值方法是非常有用的,比如变量引用的列的数据类型和大小改变了,如果使用了%TYPE,那么用户就不必修改代码,否则就必须修改代码。 

 

例: 

  v_empno SCOTT.EMP.EMPNO%TYPE; 

  v_salary EMP.SALARY%TYPE; 

   不但列名可以使用%TYPE,而且变量、游标、记录,或声明的常量都可以使用%TYPE。这对于定义相同数据类型的变量非常有用。 

    DELCARE 

    V_A NUMBER(5):=10; 

    V_B V_A%TYPE:=15; 

    V_C V_A%TYPE; 

    BEGIN 

      DBMS_OUTPUT.PUT_LINE 

      ('V_A='||V_A||'V_B='||V_B||'V_C='||V_C); 

    END 

    

    SQL>/ 

    V_A=10 V_B=15 V_C= 

     PL/SQL procedure successfully completed. 

     SQL> 

      

其他DML语句 

    其它操作数据的DML语句是:INSERTUPDATEDELETELOCK TABLE,这些语句在PL/SQL中的语法与在SQL中的语法相同。我们在前面已经讨论过DML语句的使用这里就不再重复了。在DML语句中可以使用任何在DECLARE部分声明的变量,如果是嵌套块,那么要注意变量的作用范围。 

 

例: 

  CREATE OR REPLACE PROCEDURE FIRE_EMPLOYEE (pempno in number) 

   AS 

    v_ename EMP.ENAME%TYPE; 

    BEGIN 

     SELECT ename INTO v_ename 

      FROM emp 

      WHERE empno=p_empno; 

      INSERT INTO FORMER_EMP(EMPNO,ENAME) 

      VALUES (p_empno,v_ename); 

      DELETE FROM emp 

      WHERE empno=p_empno; 

      UPDATE former_emp 

      SET date_deleted=SYSDATE 

      WHERE empno=p_empno; 

      

    EXCEPTION 

       WHEN NO_DATA_FOUND THEN 

       DBMS_OUTPUT.PUT_LINE('Employee Number Not Found!'); 

    END 

 

DML语句的结果 

    当执行一条DML语句后,DML语句的结果保存在四个游标属性中,这些属性用于控制程序流程或者了解程序的状态。当运行DML语句时,PL/SQL打开一个内建游标并处理结果,游标是维护查询结果的内存中的一个区域,游标在运行DML语句时打开,完成后关闭。隐式游标只使用SQL%FOUND,SQL%NOTFOUND,SQL%ROWCOUNT三个属性.SQL%FOUND,SQL%NOTFOUND是布尔值,SQL%ROWCOUNT是整数值。 

 

SQL%FOUNDSQL%NOTFOUND 

    在执行任何DML语句前SQL%FOUNDSQL%NOTFOUND的值都是NULL,在执行DML语句后,SQL%FOUND的属性值将是: 

 

. TRUE :INSERT 

. TRUE :DELETEUPDATE,至少有一行被DELETEUPDATE. 

. TRUE :SELECT INTO至少返回一行 

SQL%FOUNDTRUE,SQL%NOTFOUNDFALSE 

 

SQL%ROWCOUNT 

   在执行任何DML语句之前,SQL%ROWCOUNT的值都是NULL,对于SELECT             INTO语句,如果执行成功,SQL%ROWCOUNT的值为1,如果没有成功,SQL%ROWCOUNT的值为0,同时产生一个异常NO_DATA_FOUND. 

 

SQL%ISOPEN 

  SQL%ISOPEN是一个布尔值,如果游标打开,则为TRUE, 如果游标关闭,则为FALSE.对于隐式游标而言SQL%ISOPEN总是FALSE,这是因为隐式游标在DML语句执行时打开,结束时就立即关闭。 

 

事务控制语句 

    事务是一个工作的逻辑单元可以包括一个或多个DML语句,事物控制帮助用户保证数据的一致性。如果事务控制逻辑单元中的任何一个DML语句失败,那么整个事务都将回滚,在PL/SQL中用户可以明确地使用COMMITROLLBACKSAVEPOINT以及SET TRANSACTION语句。 

     COMMIT语句终止事务,永久保存数据库的变化,同时释放所有LOCK,ROLLBACK终止现行事务释放所有LOCK,但不保存数据库的任何变化,SAVEPOINT用于设置中间点,当事务调用过多的数据库操作时,中间点是非常有用的,SET TRANSACTION用于设置事务属性,比如read-write和隔离级等。 

 

显式游标 

    当查询返回结果超过一行时,就需要一个显式游标,此时用户不能使用select into语句。PL/SQL管理隐式游标,当查询开始时隐式游标打开,查询结束时隐式游标自动关闭。显式游标在PL/SQL块的声明部分声明,在执行部分或异常处理部分打开,取数据,关闭。 

 

精彩的近乎完美的分页存储过程

 

CREATE procedure main_table_pwqzc
(@pagesize int,
@pageindex int,
@docount bit,
@this_id)
as
if(@docount=1)
begin
select count(id) from luntan where this_id=@this_id
end
else
begin
declare @indextable table(id int identity(1,1),nid int)
declare @PageLowerBound int
declare @PageUpperBound int
set @PageLowerBound=(@pageindex-1)*@pagesize
set @PageUpperBound=@PageLowerBound+@pagesize
set rowcount @PageUpperBound
insert into @indextable(nid) select id from luntan where this_id=@this_id order by reply_time desc
select a.* from luntan a,@indextable t where a.id=t.nid
and t.id>@PageLowerBound and t.id<=@PageUpperBound order by t.id
end
GO

存储过程会根据传入的参数@docount来确定是不是要返回所有要分页的记录总数
特别是这两行
set rowcount @PageUpperBound
insert into @indextable(nid) select id from luntan where this_id=@this_id order by reply_time desc

真的是妙不可言!!set rowcount @PageUpperBound当记录数达到@PageUpperBound时就会停止处理查询
,select id 只把id列取出放到临时表里,select a.* from luntan a,@indextable t where a.id=t.nid
and t.id>@PageLowerBound and t.id<=@PageUpperBound order by t.id
而这句也只从表中取出所需要的记录,而不是所有的记录,结合起来,极大的提高了效率!!
妙啊,真的妙!!!!

CREATE PROCEDURE Paging_RowCount
(
@Tables varchar(1000),
@PK varchar(100),
@Sort varchar(200) = NULL,
@PageNumber int = 1,
@PageSize int = 10,
@Fields varchar(1000) = '*',
@Filter varchar(1000) = NULL,
@Group varchar(1000) = NULL)
AS

/*Default Sorting*/
IF @Sort IS NULL OR @Sort = ''
 SET @Sort = @PK

/*Find the @PK type*/
DECLARE @SortTable varchar(100)
DECLARE @SortName varchar(100)
DECLARE @strSortColumn varchar(200)
DECLARE @operator char(2)
DECLARE @type varchar(100)
DECLARE @prec int

/*Set sorting variables.*/ 
IF CHARINDEX('DESC',@Sort)>0
 BEGIN
  SET @strSortColumn = REPLACE(@Sort, 'DESC', '')
  SET @operator = '<='
 END
ELSE
 BEGIN
  IF CHARINDEX('ASC', @Sort) = 0
   SET @strSortColumn = REPLACE(@Sort, 'ASC', '')
  SET @operator = '>='
 END


IF CHARINDEX('.', @strSortColumn) > 0
 BEGIN
  SET @SortTable = SUBSTRING(@strSortColumn, 0, CHARINDEX('.',@strSortColumn))
  SET @SortName = SUBSTRING(@strSortColumn, CHARINDEX('.',@strSortColumn) + 1, LEN(@strSortColumn))
 END
ELSE
 BEGIN
  SET @SortTable = @Tables
  SET @SortName = @strSortColumn
 END

SELECT @type=t.name, @prec=c.prec
FROM sysobjects o
JOIN syscolumns c on o.id=c.id
JOIN systypes t on c.xusertype=t.xusertype
WHERE o.name = @SortTable AND c.name = @SortName

IF CHARINDEX('char', @type) > 0
   SET @type = @type + '(' + CAST(@prec AS varchar) + ')'

DECLARE @strPageSize varchar(50)
DECLARE @strStartRow varchar(50)
DECLARE @strFilter varchar(1000)
DECLARE @strSimpleFilter varchar(1000)
DECLARE @strGroup varchar(1000)

/*Default Page Number*/
IF @PageNumber < 1
 SET @PageNumber = 1

/*Set paging variables.*/
SET @strPageSize = CAST(@PageSize AS varchar(50))
SET @strStartRow = CAST(((@PageNumber - 1)*@PageSize + 1) AS varchar(50))

/*Set filter & group variables.*/
IF @Filter IS NOT NULL AND @Filter != ''
 BEGIN
  SET @strFilter = ' WHERE ' + @Filter + ' '
  SET @strSimpleFilter = ' AND ' + @Filter + ' '
 END
ELSE
 BEGIN
  SET @strSimpleFilter = ''
  SET @strFilter = ''
 END
IF @Group IS NOT NULL AND @Group != ''
 SET @strGroup = ' GROUP BY ' + @Group + ' '
ELSE
 SET @strGroup = ''
 
/*Execute dynamic query*/ 
EXEC(
'
DECLARE @SortColumn ' + @type + '
SET ROWCOUNT ' + @strStartRow + '
SELECT @SortColumn=' + @strSortColumn + ' FROM ' + @Tables + @strFilter + ' ' + @strGroup + ' ORDER BY ' + @Sort + '
SET ROWCOUNT ' + @strPageSize + '
SELECT ' + @Fields + ' FROM ' + @Tables + ' WHERE ' + @strSortColumn + @operator + ' @SortColumn ' + @strSimpleFilter + ' ' + @strGroup + ' ORDER BY ' + @Sort + '
'
)
GO

8月3日

在oracle数据库中如何插入CLOB值

oracle中最常用的varcher2类型最多只能存储4000个字节的内容,一般情况下是能够满足用户的需求的。但是在一些特殊情况下(如要存储图片或者要存储的内容超过了4000个字节),varcher2就满足不了这个需求了。这个时候我们可以借助于oracle里面的大字段CLOB后者BLOB。举例如下: 首先,在数据库中建一张表news,为了简单起见,只有一个字段content(CLOB)。做好准备工作后就可以开始我们的CLOB之旅了。 以下是插入CLOB的代码: import java.sql.*; import java.io.*; public class TestClob{ public void TestClob(){} public static void main(String args[]){ try{ Class.forName("oracle.jdbc.driver.OracleDriver"); Connectionconn=DriverManager.getConnection ("jdbc:oracle:thin:@localhost:1521:ora32","tjpt","tjpt"); conn.setAutoCommit(false); //第一步:插入一个空的CLOB String sql1="insert into news(content,id) values (EMPTY_CLOB(),'1')"; PreparedStatement ps1=conn.prepareStatement(sql1); ps1.executeUpdate(); ps1.close(); //第二步:取出该CLOB String sql2="select content from news for update"; PreparedStatement ps2=conn.prepareStatement(sql2); ResultSet rs2=ps2.executeQuery(); while (rs2.next()){ oracle.sql.CLOB clob=(oracle.sql.CLOB)rs2.getClob(1); BufferedWriter out=new BufferedWriter(clob.getCharacterOutputStream()); String content="1234";//假定这是新闻的内容,当然可以也可以是其他的内容 out.write(content,0,content.length()); out.close(); } conn.commit(); } catch(Exception e){e.printStackTrace();} } } 既然插入进去了,那我们还得要检验一下:插进去的是不是你想插进去的内容?以下就是读取CLOB的代码: import java.sql.*; import java.io.*; public class ReadClob{ public void ReadClob(){} public static void main(String args[]){ try{ Class.forName("oracle.jdbc.driver.OracleDriver"); Connection conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ora32","tjpt","tjpt"); String sql1="select content from news"; PreparedStatement ps1=conn.prepareStatement(sql1); ResultSet rs1=ps1.executeQuery(); while (rs1.next()){ oracle.sql.CLOB clob=(oracle.sql.CLOB)rs1.getClob(1); BufferedReader in=new BufferedReader(clob.getCharacterStream()); StringWriter out=new StringWriter(); int c; while((c=in.read())!=-1){ out.write(c); } String content=out.toString(); System.out.println (content);//输出CLOB内容 } } catch(Exception e){e.printStackTrace();} }} 本文引用通告地址: http://blog.csdn.net/CMTobby/services/trackbacks/436424.aspx
7月15日

jsp连接数据库 大全

许多初学jsp的网友经常会问数据库怎么连接啊,我总结一下供大家参考, 其实这种把数据库逻辑全部放在jsp里未必是好的做法,但是有利于初学者学习,当大家学到一定程度的时候, 可以考虑用MVC的模式开发。在练习这些代码的时候,你一定将jdbc的驱动程序放到服务器的类路径里, 然后要在数据库里建一个表test,有两个字段比如为test1,test2,可以用下面SQL建 create table test(test1 varchar(20),test2 varchar(20) 然后向这个表写入一条测试纪录,那么现在开始我们的jsp和数据库之旅吧。 一、jsp连接Oracle8/8i/9i数据库(用thin模式) testoracle.jsp如下: 您的第一个字段内容为: 您的第二个字段内容为: 二、jsp连接Sql Server7.0/2000数据库 testsqlserver.jsp如下: 您的第一个字段内容为: 您的第二个字段内容为: 三、jsp连接DB2数据库 testdb2.jsp如下: 您的第一个字段内容为: 您的第二个字段内容为: 四、jsp连接Informix数据库 testinformix.jsp如下: 您的第一个字段内容为: 您的第二个字段内容为: 五、jsp连接Sybase数据库 testmysql.jsp如下: 您的第一个字段内容为: 您的第二个字段内容为: 六、jsp连接MySQL数据库 testmysql.jsp如下: 您的第一个字段内容为: 您的第二个字段内容为: 七、jsp连接PostgreSQL数据库 testmysql.jsp如下: 您的第一个字段内容为: 您的第二个字段内容为:

File存入到数据库的办法

当需要把文件存入到服务器端的数据库中,有四种方式可行: 1.servlet/jsp+fileupload/smartupload/自己编一个实现接受文件的javaBean.然后调用相关的程序,把文件存入数据库中。这也是通常的选择。 2.通过数据库的存储过程,直接用sql来操作可以实现,需要访问文件系统。见全文搜索中向数据库中存入文件的办法。 3.rmi客户/服务器的方式,由于rmi对实现的接口的参数要求是可串行化的,因此可以选用byte[]或fileupload组件中fileItem对象等,由于在rmi中通常使用双方协商好的对象类型,因此在文件传输,可选用定义一继承seriable接口的类对象,包含文件和文件的相关信息。 4.虽然EJB是不能访问文件系统,而且要求实现的接口的参数要求是可串行化的,还必须是EJB规范下的数据类型(基本的数据类型)因此不能选用java.io包下的类(非串行化)和像fileupload组件等之外的类对象(串行化)作为参数。但是在EJB内部是可以使用java.io包中的对象。通过EJB来实现把文件存入到数据库的方法: 1).用byte[]作为远程接口的参数类型. 2).用file,fileinputstream,datoutputstream来实现文件对象, 3).然后以文件对象流的形式存入数据库中。 在EJB中的实现方法: public String upFile(byte[] fileByte,java.lang.String fileName ){ try{ System.out.println("fdjkj"); File f=new File(fileName); DataOutputStream fileout=new DataOutputStream(new FileOutputStream(f)); FileInputStream fi=new FileInputStream(f); int li=fi.read(fileByte,0,fileByte.length-1); fileout.write(fileByte,0,fileByte.length-1);//这两句不能颠倒,上面依据是表示开始向fileInputStream中读入数据,这一句才是把byte[]中的数据读入到流中 System.out.println("fdjkj"); String dName="com.microsoft.jdbc.sqlserver.SQLServerDriver"; String conURL="jdbc:microsoft:sqlserver://159.164.176.116:1038;DatabaseName=Digital Lab"; // File f1=new File(""+fds.get("fileID") ); Connection con=null; Statement stm=null; ResultSet rs=null; PreparedStatement ps=null; Class.forName(dName).newInstance();System.out.println("fdjkj"); con=DriverManager.getConnection(conURL,"gaolong1","831001");System.out.println("fdjkj"); String sql="insert into testEJBFile values('"+fileName+"',?,"+(fileByte.length-1)+")"; //String sel="select * from xinxi where changhao=215;"; //String sel="select * from custom where yuming='212';"; ps=con.prepareStatement(sql);System.out.println("fdsssssjkj"); ps.setBinaryStream(1,fi,(int)fileByte.length-1); // ps.setBytes(1,b); ps.executeUpdate();System.out.println("fdjkj"); ps.close(); return "ok"; }catch(Exception e){ e.printStackTrace(); return "false"; } } } 调用EJB的客户端程序: package com.J2EE.first.interfaces; import javax.naming.Context; import javax.naming.InitialContext; import javax.rmi.PortableRemoteObject; import java.util.Properties; import java.io.*; /** * @author gaolong1 * * TODO 要更改此生成的类型注释的模板,请转至 * 窗口 - 首选项 - Java - 代码样式 - 代码模板 */ public class EJBClient { public static void main(String[] args) { try{ String url="t3://59.64.76.16:7001"; Properties prop=new Properties(); prop.put(Context.PROVIDER_URL,url); prop.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory"); Context ctx=new InitialContext(prop); Object obj=ctx.lookup("ejb/com/J2EE/first/ejb/HelloHome"); /* Properties pr=System.getProperties(); Context ctx=new InitialContext(pr); Object obj=ctx.lookup("ejb/com/fristEJB/Trader/ejb/TraderHome"); */ HelloHome trH=(HelloHome) PortableRemoteObject.narrow(obj,HelloHome.class); Hello tr=trH.create(); System.out.println(tr.hello()); File f=new File("12.xml"); BufferedReader br=new BufferedReader(new InputStreamReader(new FileInputStream(f),"UTF-8")); String str=""; String strup=""; while((str=br.readLine())!=null) strup+=str; System.out.println(strup); byte[] bt=strup.getBytes();//把文件变成byte数组 System.out.println(bt); String test=tr.upFile(bt,"12.xml");//调用EJB程序 System.out.println(test); tr.remove(); }catch(Exception e){ e.printStackTrace(); } } } 在EJB中实现文件存入数据库的方法,就是通过把string或byte[]变成文件对象,然后存入到数据库中,但在操作的过程中要注意EJB不能操作文件系统,同时也不因为这而认为在EJB中不能操作文件流。操作文件流可能性能有所下降。使用J2EE组件时要严格注意规范,在规范内实现需要的功能。

彻底搞定JSP的在线人数

/**这是管理user信息的类 文件名为onLineUser.java 欢迎访问javajia家(http://www.javajia.com),由yuking制作。2001.1.1 */ import javax.servlet.http.*; import javax.servlet.*; import java.util.*; public class onLineUser implements HttpSessionBindingListener { public onLineUser(){ } private Vector users=new Vector(); public int getCount(){ users.trimToSize(); return users.capacity(); } public boolean existUser(String userName){ users.trimToSize(); boolean existUser=false; for (int i=0;i 搞定JSP在线人数

登陆成功,欢迎您访问Java家!

yuking制作

 

//////////////////////////////////////////////////////////////////////////////////// 搞定JSP在线人数

登陆成功,欢迎您访问Java家!

yuking制作

 

退出系统

6月30日

表格内容自动换行

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
 
6月22日

轻松玩转花样表单

 本专题从最基础的表单知识,到表单的高级应用,让你有一个比较全面地认识,相信你在读完本专题以后,一定会对表单非常熟悉。

一、表单概述


  表单,在网页中的作用不可小视,主要负责数据采集的功能,比如你可以采集访问者的名字和e-mail地址、调查表、留言簿等等。

1、表单的组成


  一个表单有三个基本组成部分:

  • 表单标签:这里面包含了处理表单数据所用CGI程序的URL以及数据提交到服务器的方法。
  • 表单域:包含了文本框、密码框、隐藏域、多行文本框、复选框、单选框、下拉选择框和文件上传框等。
  • 表单按钮:包括提交按钮、复位按钮和一般按钮;用于将数据传送到服务器上的CGI脚本或者取消输入,还可以用表单按钮来控制其他定义了处理脚本的处理工作。
  为了顾及不同的网页设计工具,本文只讲述代码的设计,不具体讲述操作方法,下面就是表单的HTML代码设计要点:

1.1 表单标签<form></form>

  功能:用于申明表单,定义采集数据的范围,也就是<form>和</form>里面包含的数据将被提交到服务器或者电子邮件里。

  语法:<FORM ACTION="URL" METHOD="GET|POST" ENCTYPE="MIME" TARGET="...">. . .</FORM>

  属性解释见下表:

action=url 指定一来处理提交表单的格式.它可以是一个URL地址(提交给程式)或一个电子邮件地址. method=get或post 指明提交表单的HTTP方法.可能的值为:
  1. post:POST方法在表单的主干包含名称/值对并且无需包含于action特性的URL中.
  2. get:不赞成。GET方法把名称/值对加在action的URL后面并且把新的URL送至服务器.这是往前兼容的缺省值.这个值由于国际化的原因不赞成使用.
enctype=cdata 指明用来把表单提交给服务器时(当method值为"post")的互联网媒体形式.这个特性的缺省值是"application/x-www-form-urlencoded" TARGET="..." 指定提交的结果文档显示的位置:
  1. _blank :在一个新的、无名浏览器窗口调入指定的文档;
  2. _self :在指向这个目标的无素的相同的框架中调入文档;
  3. _parent :把文档调入当前框的直接的父FRAMESET框中;这个值在当前框没有父框时等价于_self;
  4. _top :把文档调入原来的最顶部的浏览器窗口中(因此取消所有其它框架);这个值等价于当前框没有你框时的_self.


  例如:
  <form action="http://www.yesky.com/test.asp" method="post" target="_blank">...</form>
  表示表单将向http://www.yesky.com/test.asp以post的方式提交,提交的结果在新的页面显示,数据提交的媒体方式是默认的application/x-www-form-urlencoded方式;
1.2 表单域

  表单域包含了文本框、多行文本框、密码框、隐藏域、复选框、单选框和下拉选择框等,用于采集用户的输入或选择的数据,下面分别讲述这些表单域的代码格式:

1.2.1 文本框

  文本框是一种让访问者自己输入内容的表单对象,通常被用来填写单个字或者简短的回答,如姓名、地址等。
  代码格式:<input type="text" name="..." size="..." maxlength="..." value="...">

  属性解释:
  type="text"定义单行文本输入框;
  name属性定义文本框的名称,要保证数据的准确采集,必须定义一个独一无二的名称;
  size属性定义文本框的宽度,单位是单个字符宽度;
  maxlength属性定义最多输入的字符数。
  value属性定义文本框的初始值

样例1:

样例1代码:

<input type="text" name="example1" size="20" maxlength="15">

1.2.2 多行文本框

  也是一种让访问者自己输入内容的表单对象,只不过能让访问者填写较长的内容。
  代码格式:<TEXTAREA name="..." cols="..." rows="..." wrap="VIRTUAL"></TEXTAREA>
  属性解释:
  name属性定义多行文本框的名称,要保证数据的准确采集,必须定义一个独一无二的名称;
  cols属性定义多行文本框的宽度,单位是单个字符宽度;
  rows属性定义多行文本框的高度,单位是单个字符宽度;
  wrap属性定义输入内容大于文本域时显示的方式,可选值如下:

  • 默认值是文本自动换行;当输入内容超过文本域的右边界时会自动转到下一行,而数据在被提交处理时自动换行的地方不会有换行符出现;
  • Off,用来避免文本换行,当输入的内容超过文本域右边界时,文本将向左滚动,必须用Return才能将插入点移到下一行;
  • Virtual,允许文本自动换行。当输入内容超过文本域的右边界时会自动转到下一行,而数据在被提交处理时自动换行的地方不会有换行符出现;
  • Physical,让文本换行,当数据被提交处理时换行符也将被一起提交处理。


样例2:


  

样例2代码:

<TEXTAREA name="example2" cols="20" rows="2" wrap="PHYSICAL"></TEXTAREA>
  

1.2.3 密码框

  是一种特殊的文本域,用于输入密码。当访问者输入文字时,文字会被星号或其它符号代替,而输入的文字会被隐藏。

  代码格式:<input type="password" name="..." size="..." maxlength="...">

  属性解释:
  type="password"定义密码框;
  name属性定义密码框的名称,要保证数据的准确采集,必须定义一个独一无二的名称;
  size属性定义密码框的宽度,单位是单个字符宽度;
  maxlength属性定义最多输入的字符数。

样例3:

样例3代码:

<input type="password" name="example3" size="20" maxlength="15">


1.2.4 隐藏域

  隐藏域是用来收集或发送信息的不可见元素,对于网页的访问者来说,隐藏域是看不见的。当表单被提交时,隐藏域就会将信息用你设置时定义的名称和值发送到服务器上。

  代码格式:<input type="hidden" name="..." value="...">

  属性解释:
  type="hidden"定义隐藏域;
  name属性定义隐藏域的名称,要保证数据的准确采集,必须定义一个独一无二的名称;
  value属性定义隐藏域的值
  例如:<input type="hidden" name="ExPws" value="dd">


1.2.5 复选框

  复选框允许在待选项中选中一项以上的选项。每个复选框都是一个独立的元素,都必须有一个唯一的名称。

  代码格式:<INPUT type="checkbox" name="..." value="...">

  属性解释:
  type="checkbox"定义复选框;
  name属性定义复选框的名称,要保证数据的准确采集,必须定义一个独一无二的名称;
  value属性定义复选框的值

样例4: yesky.com Chinabyte.com

样例4代码:
  <input type="checkbox" name="yesky" value="09">yesky.com
  <input type="checkbox" name="Chinabyte" value="08">Chinabyte.com

1.2.6 单选框

  当需要访问者在待选项中选择唯一的答案时,就需要用到单选框了。

  代码格式:<input type="radio" name="..." value="...">

  属性解释:
  type="radio"定义单选框;
  name属性定义单选框的名称,要保证数据的准确采集,单选框都是以组为单位使用的,在同一组中的单选项都必须用同一个名称;
  value属性定义单选框的值,在同一组中,它们的域值必须是不同的。

 样例5: yesky.com Chinabyte.com

样例5代码:
  <input type="radio" name="myFavor" value="1">yesky.com
  <input type="radio" name="myFavor" value="2">Chinabyte.com


1.2.7 文件上传框

  有时候,需要用户上传自己的文件,文件上传框看上去和其它文本域差不多,只是它还包含了一个浏览按钮。访问者可以通过输入需要上传的文件的路径或者点击浏览按钮选择需要上传的文件。
  注意:在使用文件域以前,请先确定你的服务器是否允许匿名上传文件。表单标签中必须设置ENCTYPE="multipart/form-data"来确保文件被正确编码;另外,表单的传送方式必须设置成POST。

  代码格式:<input type="file" name="..." size="15" maxlength="100">

  属性解释:
  type="file"定义文件上传框;
  name属性定义文件上传框的名称,要保证数据的准确采集,必须定义一个独一无二的名称;
  size属性定义文件上传框的宽度,单位是单个字符宽度;
  maxlength属性定义最多输入的字符数。

 样例6:

样例6代码:

<input type="file" name="myfile" size="15" maxlength="100">


1.2.8 下拉选择框

  下拉选择框允许你在一个有限的空间设置多种选项。

  代码格式:
  <select name="..." size="..." multiple>
  <option value="..." selected>...</option>
  ...
  </select>

  属性解释:
  size属性定义下拉选择框的行数;
  name属性定义下拉选择框的名称;
  multiple属性表示可以多选,如果不设置本属性,那么只能单选;
  value属性定义选择项的值;
  selected属性表示默认已经选择本选项。

 样例7: yesky.com chinabyte.com

样例7代码:
  <select name="mySel" size="1">
  <option value="1" selected>yesky.com</option>
  <option value="d2">chinabyte.com</option>
  </select>

 样例8:
   yesky.com chinabyte.com internet.com 按Ctrl可以多选

样例8代码:
  <select name="mySelt" size="3" multiple>
  <option value="1" selected>yesky.com</option>
  <option value="d2">chinabyte.com</option>
  <option value="3">internet.com</option>
  </select>

1.3 表单按钮

  表单按钮控制表单的运作。

1.3.1 提交按钮

  提交按钮用来将输入的信息提交到服务器。

  代码格式:<input type="submit" name="..." value="...">

  属性解释:
  type="submit"定义提交按钮;
  name属性定义提交按钮的名称;
  value属性定义按钮的显示文字;

 样例9:

样例9代码:

<input type="submit" name="mySent" value="发送">

1.3.2 复位按钮

  复位按钮用来重置表单。

  代码格式:<input type="reset" name="..." value="...">

  属性解释:
  type="reset"定义复位按钮;
  name属性定义复位按钮的名称;
  value属性定义按钮的显示文字;

 样例10:

样例10代码:

<input type="reset" name="myCancle" value="取消">

1.3.3 一般按钮

  一般按钮用来控制其他定义了处理脚本的处理工作。

  代码格式:<input type="button" name="..." value="..." onClick="...">

  属性解释:
  type="button"定义一般按钮;
  name属性定义一般按钮的名称;
  value属性定义按钮的显示文字;
  onClick属性,也可以是其它的事件,通过指定脚本函数来定义按钮的行为;

样例11:

样例11代码:
  <input type="button" name="myB" value="保存" onClick="javascript:alert('it is a button')">

二、表单外观的美化

  很多时候,我们仅仅为了实现数据采集这个功能来使用表单,常看到的表单都是“千人一面”、毫无生气,本专题尝试着来改变这一现象,试图赋予表单一个丰富多彩的面貌。
表单的外观,也是最为直接的花样,可以通过改变它来实现特效,本文分两个出发点来讲述:CSS魔法和图像魔法。

  1、CSS魔法


CSS,就是大家知道的层叠样式单,它可以定义页面元素的外观,包括字体样式、背景颜色和图像样式、边框样式、补白样式、边界样式等等,下面就从这几个方面出发,讨论怎样将CSS应用到表单中,彻底美化它!

  1.1 字体样式的应用


  字体样式包括:字体族科(font-family)、字体风格(font-style)、字体变形(font-variant)、字体加粗(font-weight)、字体大小(font-size)、字体(font),具体的定义方法,在这里不详细讲述,可以参考它的资料。
  也许你已经注意到,按钮上的文字不漂亮,其实可以通过CSS字体样式来解决,同样地,其它的几个涉及到文字的表单项,例如,文本框、多行文本框、口令框、下拉选择框都可以应用字体样式。
  为了充分展示这些应用,下例特别设计了几种样式,在实际应用中,不必这么凌乱,灵活运用:

 样例12:
表单元素的字体样式展示

yesky.com redidea.net

underline css style


  分析:

  • 文本框里的文字是加粗的,大小是9pt,字体是宋体,代码:
    <input type="text" name="formExam" size="10" maxlength="10" style="font-family:宋体; font-size: 12px; font-weight: bold" value="加粗">
  • 口令框文字是红色的,代码:
    <input type="password" name="formExam3" style="font-size: 9pt; color: #FF0000" size="8" maxlength="8">
  • 下拉框文字颜色是红色的,字体是Verdana,大小是9pt,代码:
    <select name="select" size="1" style="font-family:Verdana,Arial; font-size: 9pt; color: #FF0000">
    <option value="2" selected>yesky.com</option>
    <option value="1">redidea.net</option>
    </select>
  • 多行文本框了的字体是Verdana,有下划线,大小是9pt,代码:
    <TEXTAREA name="formExam2" cols="30" rows="3" style="font-family:Verdana, Arial; font-size: 9pt; color: #000099; text-decoration: underline" align=right>underline css style</TEXTAREA>
  • 发送1和发送2按钮的文字不同,是因为发送1按钮使用了9pt的宋体文字,所以比较美观,发送1按钮的代码:
    <input type="submit" name="Submit" value="发送1" style="font-family:宋体; font-size: 9pt;">


  小结:只要我们对字体的样式熟悉了,就可以灵活多变,不一定要在标签里面使用style来定义,完全可以在<head>里定义,或者外部引用CSS文件,用到的时候引用一下就能达到预期的效果。

1.2 背景颜色和图像样式的应用

  有很多时候,网页由于颜色的搭配,不得不对表单的背景颜色和图像样式进行设计,背景颜色利用background-color属性,背景图像利用background-image属性,颜色和图像同样能够得到意想不到的效果。

 样例13: 表单元素的背景展示
复选 单选 yesky.com redidea.com chinabyte.com sina.com sohu.com



  分析:

  • 文本框背景是黑色的,字体是白色的,代码:
    <input type="text" name="RedFld" size="10" maxlength="10" style="color: #FFFFFF; background-color: #000000">
  • 口令框背景是灰色的,代码:
    <input type="password" name="RedFld3" size="10" maxlength="10" style="background-color: #999999">
  • 单选和复选按钮的背景是红色的,代码:
    <input type="checkbox" name="checkbox" value="checkbox" style="background-color: #FF0000">
    <input type="radio" name="radiobutton" value="radiobutton" style="background-color: #FF0000">
  • 下拉选择框的选项是丰富多彩的背景,代码:
    <select name="select2" size="1">
    <option selected style="background-color: #FF0000">yesky.com</option>
    <option style="background-color: #0000CC">redidea.com</option>
    <option style="background-color: #009900">chinabyte.com</option>
    <option style="background-color: #ff33cc">sina.com</option>
    <option style="background-color: #999999">sohu.com</option>
    </select>
  • 多行文本框的背景是一个图像,代码:
    <TEXTAREA name="RedFld2" cols="25" rows="3" wrap="VIRTUAL" style="background-image: url(back.gif)"></TEXTAREA>
  • submit1按钮的背景是黄色的,代码:
    <input type="submit" name="Submit3" value="Submit1" style="background-color: #FF9900">
  • submit2按钮的背景是一个图像,代码:
    <input type="submit" name="Submit22" value="Submit2" style="background-image: url(back.gif)">


  小结:用好background-color属性和background-image属性,就可以设计很出“色”表单了。

1.3 边框样式的应用

  也许你觉得表单的边框过于死板,我们能否设计单线条,或者其它的边框样式呢?当然可以!

  和边框有关的属性有:边框式样border-style、上边框border-top、右边框border-right、下边框border-bottom、左边框border-left、边框颜色border-colr、边框宽度 border-width、上边框宽度border-top-width、右边框宽度border-right-width、下边框宽度border-bottom-width、左边框宽度border-left-width、边框 border,这里不作详细的讲述,请参考有关资料。

 样例14:
8种边框形式的展示


复选 单选
  分析:

  • 文本框有8种类型边框样式,即border-style,分别展示在本例中,
    边框宽度的设置有一个规律:
    border-width: [ thin | medium | thick | <长度> ]{1,4}
    边框宽度用一到四个值来设置元素的边框宽度,它们分别被应用于上、右、下和左边框宽度。如果只给出一个值,它被应用于所有边框宽度。如果两个或三个值给出了,省略了的值与对边相等
    例如:<input type="text" name="RedF" style="border-color: #006600; border-style: dotted; border-width: 1px">
    边框颜色的设置有一个规律:
    border-colr: <颜色>{1,4}
    边框颜色用一到四个值来设置元素的边框颜色。如果四个值都给出了,它们分别被应用于上、右、下和左边框颜色。如果只给出一个值,它被应用于所有边框颜色。如果两个或三个值给出了,省略了的值与对边相等。
  • 对于多行文本框以及按钮,设置边框的方法和文本框一样,不再陈述;
  • 由于下拉选择框Select不支持边框的设置,所以对它设置是徒劳的;
  • 单选按钮和复选按钮的边框,设置的效果不十分协调,所以建议不要对它们设置,不然有“画蛇添足”之感;


 样例15:
边框的特殊设计展示

  聪明的读者一定会想到,如果设计单边框,一定更加漂亮,对!下面我们来尝试以下部分边框的设置效果,本例仅仅以Solid和dotted两种类型的边框作演示,其它类型的边框原理相同:
代码:style="background-color: #FFFFFF; border-color: #000099; border-style: solid; border-width: 0px 0px 1px"


代码:style="background-color: #FFFFFF; border-color: #CCCCCC black #FF0000; border-style: solid; border-width: 1px 0px"


代码:style="background-color: #FFFFFF;border-left: 1px dotted #ff0000; border-right: 1px dotted #ff0000; border-top: 1px dotted #ff0000; border-bottom:1px solid #000000" 注意:边框类型的外观如下:

  • none :无边框。与任何指定的border-width值无关;
  • dotted :点线;
  • dashed :虚线;
  • solid :实线边框;
  • double :双线边框。两条单线与其间隔的和等于指定的border-width值;
  • groove :3D凹槽;
  • ridge :边框突起;
  • inset :3D凹边;
  • outset :3D凸边;


  2、图像魔法

  图像,是网页的重要元素,能否应用到表单中呢?接下来,我们用图像来改造死板的表单,分两个部分来探讨:用图像代替按钮、用背景图美化表单元素。

  2.1 用图像代替按钮


由于默认的表单按钮太丑陋,绝大多数的网站采用了图像按钮,那么,我们通过两个实例来看看怎样实现的:

样例16
:用图像代替提交按钮:

  当只有一个提交按钮的时候,可以简单地实现,不用加事件函数,代码是:
<input type="image" name="..." src="url" width="" height="..." border="...">

  除了标签改为input type="image"以外,其它的属性和<img>标签的属性是一样的,例如:
  是不是只要用图片就可以代替所有的按钮呢?是的,不过,不是上面这么简单了,必须加上事件函数,不然的话,图片都是提交按钮,不能完成复位等功能,看看下面的例子就知道了:

样例17
:用图片代替所有的表单按钮: 注意:

  • 代替submit按钮的图片代码格式是
    <input type="image" name="..." src="..." onClick="document.formName.submit()">
  • 代替reset按钮的代码图片格式是
    <a href="javascript:document.formName.reset();"><img border=0 src="..."></a>
    注:这里的formName是表单的name属性值。

  2.2 用背景图美化表单元素

  其实,前面已经提到过,用background-image:url()属性来定义表单元素的背景图,这里仅举一例,可以看到,除了select没有效果以外,其它的都可以配合网页的背景来设置它们。

样例18
:背景图的设置 www.yesky.com redidea.com www.chinabyte.com

三、表单的提交

  既然表单是用来采集用户输入的数据,那么,就应该保证用户的数据被准确地提交到预定的地点,也就是说,我们在表单提交的时候,应该对用户的数据进行检验,一来可以避免用户误输数据,二来可以避免用户输入非法的,或者说不合格的数据;检验合格以后,还要保证用户的数据提交到特定的程序。

  1.数据的检验

  数据的检验,通常有两种程序:客户端检验和服务器端检验。客户端检验,比较快,服务器端检验,相对来说比较慢,为了确保安全,通常同时采用,这样就可以避免用户刻意破坏。
  不管采用什么方式菁煅榈脑矶际且谎模坏┯没淙氲氖莶环瞎娑ǎ捅ù恚笥没е匦率淙耄突Ф思煅槌J褂肑avascrip脚本,服务器端的视系统而定,本文不对数据检验的具体程序设计进行探讨,仅仅列举几个例子来说明。

 样例19
:必填项,以及简单的数据类型检验 以下带*的必须输入:
姓名: *
Email: *

  分析:

  • 本例给表单添加了onSubmit事件,通过onSubmit="return CheckDate()"指定提交前,必须通过函数CheckDate()来检验,如果不合格,返回输入数据;
  • 数据检验的函数如下:
    <script>
    function CheckDate(){
    //取得输入的数据
    userName = document.RedForm.userName.value;
    userEmail = document.RedForm.userEmail.value;
    //如果没有输入姓名
    if (userName=="") {
    alert("请输入姓名");
    document.RedForm.userName.focus();
    return false;
    }else{
    //如果没有输入Email,或者Email地址错误(不含@)
    if ((userEmail=="")||(userEmail.indexOf("@")==-1)) {
    alert("请重新输入Email地址");
    document.RedForm.userEmail.focus();
    return false;
    }else return true;
    }
    }
    </script>


  2.表单的分支提交

  有的时候,表单需要根据用户的选择,提交到不同的程序,怎么做呢?
  通过脚本来检测用户的选择分支,从而向不同的程序提交表单,看看样例:

 样例20:
分支提交 用户名: 密码:
公司用户 个人用户
  分析:
这里首先用到的是form的onSubmit="TwoSubmit(this)"
然后根据选择的分支,来分别递交到不同的程序,TwoSubmit()函数如下:

<script>
function TwoSubmit(form){
if (form.Ref[0].checked){
form.action = "cop.asp";//这里是分之一
}else{
form.action = "ind.asp";//这里是分之二
}
form.submit();
}
</script>

  3.用任何元素提交表单

  是不是只有按钮或者图片按钮才能提交表单呢?当然不是,实际上,任何页面元素都可以提交表单,不过嘛,都是通过脚本来完成的,下面我们就使用链接来代替Submit按钮:

 样例21
:用链接来提交表单
用户名: 密码: 登录 清空
  分析:

  通过onClick="document.form.submit()"来提交表单;用onClick="document.form.reset()"来复位表单,这样一来,任何一个元素都可以实现提交表单了。

四、表单的常用技巧

  这些常用技巧,往往是和事件以及脚本联系在一起,本文注重功能,至于脚本,就不一一详细分析。常见的技巧有:下拉跳转菜单,表单内容的聚焦。

  1.下拉跳转菜单

  在Dreamweaver中,可以很方便地建立基于表单的下拉菜单,为了兼顾非Dreamweaver用户,这里讲述一下这种技巧。

 样例22
:基于表单的下拉跳转菜单 Chinabyte Sina netease
  分析:实际上,这里用到了一个函数,用于向选择的地址跳转,

<script language="javascript">
function FormMenu(targ,selObj,restore){
eval(targ+".location='"+selObj.options[selObj.selectedIndex].value+"'");
if (restore) selObj.selectedIndex=0;
}
</script>

  然后,给下拉选择框赋予一个事件onChange="FormMenu('parent',this,0)",就可以了。

  2.表单内容的聚焦


  内容聚焦,常用在Copy&Paste类网站上,用的好的话,可以方便用户。

 样例23
:内容自动聚焦 把你的鼠标移上来,看看 这里的内容自动选择了
  分析
: 上面分别使用了两个事件,Email的是onFocus="this.value=''",自动选择的是onMouseOver="this.select()"

  3.去掉表格和表单间的空隙

 样例24:表格和表单的空隙处理

  表格,我们常用来构架页面,可是,表格里的表单总是和表格的内容有一个空隙,对照一下:

这里有空隙
这里没有空隙
  分析:为什么右边没有空隙呢,看看右边的代码就知道了。

<table width="100%" border="1" cellspacing="1" cellpadding="1">
<tr>
<form name="form3" method="post" action="">
<td> <input type="text" name="textfield2"><br>
<input type="submit" name="Submit22" value="Submit">
这里没有空隙 </td>
</form>
</tr>
</table>

  也就是说,把<form>标签放到<tr>和<td>中间,对应的</form>放在</td>和</tr>中间!

  4.用Email提交表单(只适合Outlook用户,不适合Foxmail用户)

 样例25:Email提交表单
主题: 内容:  
  分析:看看我们的表单<form>标签就知道了,格式如下:
<form name="..." action="mailto:xxxxx@xxx.xxx?Subject=表单反馈" enctype="text/plain" method="post">...</form>
这里的mailto:后面加上要接受信息的地址,?Subject是设置默认的Email标题,enctype="text/plain"是必要的,表示信息以文本方式提交,没有任何加密,所以这种方法常用于没有Asp/Php/cgi支持的空间,也只是一个代用的方法,用户必须安装Outlook,并且是默认的邮件程序,才能顺利执行提交,据说TheBat!也可以,大家可以试验一下。

6月18日

SQL Server与Excel数据互导

  从SQL Server中导入/导出 Excel 的基本方法


/*=================== 导入/导出 Excel 的基本方法 ===================*/

从Excel文件中,导入数据到SQL数据库中,很简单,直接用下面的语句:

/*===================================================================*/
--如果接受数据导入的表已经存在
insert into 表 select * from
OPENROWSET('MICROSOFT.JET.OLEDB.4.0'
,'Excel 5.0;HDR=YES;DATABASE=c:test.xls',sheet1$)

--如果导入数据并生成表
select * into 表 from
OPENROWSET('MICROSOFT.JET.OLEDB.4.0'
,'Excel 5.0;HDR=YES;DATABASE=c:test.xls',sheet1$)


/*===================================================================*/
--如果从SQL数据库中,导出数据到Excel,如果Excel文件已经存在,而且已经按照要接收的数据创建好表头,就可以简单的用:
insert into OPENROWSET('MICROSOFT.JET.OLEDB.4.0'
,'Excel 5.0;HDR=YES;DATABASE=c:test.xls',sheet1$)
select * from 表


--如果Excel文件不存在,也可以用BCP来导成类Excel的文件,注意大小写:
--导出表的情况
EXEC master..xp_cmdshell 'bcp 数据库名.dbo.表名 out "c:test.xls" /c -/S"服务器名" /U"用户名" -P"密码"'

--导出查询的情况
EXEC master..xp_cmdshell 'bcp "SELECT au_fname, au_lname FROM pubs..authors ORDER BY au_lname" queryout "c:test.xls" /c -/S"服务器名" /U"用户名" -P"密码"'


/*--说明:
c:test.xls 为导入/导出的Excel文件名.
sheet1$     为Excel文件的工作表名,一般要加上$才能正常使用.
--*/
--上面已经说过,用BCP导出的是类Excel文件,其实质为文本文件,

--要导出真正的Excel文件.就用下面的方法


/*--数据导出EXCEL

导出表中的数据到Excel,包含字段名,文件为真正的Excel文件
,如果文件不存在,将自动创建文件
,如果表不存在,将自动创建表
基于通用性考虑,仅支持导出标准数据类型
--邹建 2003.10--*/

/*--调用示例

p_exporttb @tbname='地区资料',@path='c:',@fname='aa.xls'
--*/
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_exporttb]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[p_exporttb]
GO

create proc p_exporttb
@tbname sysname,   --要导出的表名
@path nvarchar(1000),   --文件存放目录
@fname nvarchar(250)='' --文件名,默认为表名
as
declare @err int,@src nvarchar(255),@desc nvarchar(255),@out int
declare @obj int,@constr nvarchar(1000),@sql varchar(8000),@fdlist varchar(8000)

--参数检测
if isnull(@fname,'')='' set @fname=@tbname+'.xls'

--检查文件是否已经存在
if right(@path,1)<>'' set @path=@path+''
create table #tb(a bit,b bit,c bit)
set @sql=@path+@fname
insert into #tb exec master..xp_fileexist @sql

--数据库创建语句
set @sql=@path+@fname
if exists(select 1 from #tb where a=1)
set @constr='DRIVER={Microsoft Excel Driver (*.xls)};DSN='''';READONLY=FALSE'
    +';CREATE_DB="   +';DATABASE='+@sql+'"'


--连接数据库
exec @err=sp_oacreate 'adodb.connection',@obj out
if @err<>0 goto lberr

exec @err=sp_oamethod @obj,'open',null,@constr
if @err<>0 goto lberr

/*--如果覆盖已经存在的表,就加上下面的语句
--创建之前先删除表/如果存在的话
select @sql='drop table ['+@tbname+']'
exec @err=sp_oamethod @obj,'execute',@out out,@sql
--*/

--创建表的SQL
select @sql='',@fdlist=''
select @fdlist=@fdlist+',['+a.name+']'
,@sql=@sql+',['+a.name+'] '
+case when b.name in('char','nchar','varchar','nvarchar') then
  'text('+cast(case when a.length>255 then 255 else a.length end as varchar)+')'
  when b.name in('tynyint','int','bigint','tinyint') then 'int'
  when b.name in('smalldatetime','datetime') then 'datetime'
  when b.name in('money','smallmoney') then 'money'
  else b.name end
FROM syscolumns a left join systypes b on a.xtype=b.xusertype
where b.name not in('image','text','uniqueidentifier','sql_variant','ntext','varbinary','binary','timestamp')
and object_id(@tbname)=id
select @sql='create table ['+@tbname
+']('+substring(@sql,2,8000)+')'
,@fdlist=substring(@fdlist,2,8000)
exec @err=sp_oamethod @obj,'execute',@out out,@sql
if @err<>0 goto lberr

exec @err=sp_oadestroy @obj

--导入数据
set @sql='openrowset(''MICROSOFT.JET.OLEDB.4.0'',''Excel 5.0;HDR=YES
  ;DATABASE='+@path+@fname+''',['+@tbname+'$])'

exec('insert into '+@sql+'('+@fdlist+') select '+@fdlist+' from '+@tbname)

return

lberr:
exec sp_oageterrorinfo 0,@src out,@desc out
lbexit:
select cast(@err as varbinary(4)) as 错误号
,@src as 错误源,@desc as 错误描述
select @sql,@constr,@fdlist
go
--上面是导表的,下面是导查询语句的.

6月17日

Log4j基本使用方法

  Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输出目的地,日志信息的输出格式。日志信息的优先级从高到低有ERROR、WARN、INFO、DEBUG,分别用来指定这条日志信息的重要程度;日志信息的输出目的地指定了日志将打印到控制台还是文件中;而输出格式则控制了日志信息的显示内容。

  一、定义配置文件

  其实您也可以完全不使用配置文件,而是在代码中配置Log4j环境。但是,使用配置文件将使您的应用程序更加灵活。Log4j支持两种配置文件格式,一种是XML格式的文件,一种是Java特性文件(键=值)。下面我们介绍使用Java特性文件做为配置文件的方法:

  1.配置根Logger,其语法为:

  log4j.rootLogger = [ level ] , appenderName, appenderName, …

  其中,level 是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来。 appenderName就是指定日志信息输出到哪个地方。您可以同时指定多个输出目的地。

  2.配置日志信息输出目的地Appender,其语法为:

  log4j.appender.appenderName = fully.qualified.name.of.appender.class
  log4j.appender.appenderName.option1 = value1
  …
  log4j.appender.appenderName.option = valueN

  其中,Log4j提供的appender有以下几种:
  org.apache.log4j.ConsoleAppender(控制台),
  org.apache.log4j.FileAppender(文件),
  org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),
  org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),
  org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

  3.配置日志信息的格式(布局),其语法为:

  log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class
  log4j.appender.appenderName.layout.option1 = value1
  …
  log4j.appender.appenderName.layout.option = valueN

  其中,Log4j提供的layout有以下几种:
  org.apache.log4j.HTMLLayout(以HTML表格形式布局),
  org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
  org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
  org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

  Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下: %m 输出代码中指定的消息

  %p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
  %r 输出自应用启动到输出该log信息耗费的毫秒数
  %c 输出所属的类目,通常就是所在类的全名
  %t 输出产生该日志事件的线程名
  %n 输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”
  %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
  %l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)

  二、在代码中使用Log4j

  1.得到记录器

  使用Log4j,第一步就是获取日志记录器,这个记录器将负责控制日志信息。其语法为:

  public static Logger getLogger( String name)

  通过指定的名字获得记录器,如果必要的话,则为这个名字创建一个新的记录器。Name一般取本类的名字,比如:

  static Logger logger = Logger.getLogger ( ServerWithLog4j.class.getName () )

  2.读取配置文件

  当获得了日志记录器之后,第二步将配置Log4j环境,其语法为:

  BasicConfigurator.configure (): 自动快速地使用缺省Log4j环境。
  PropertyConfigurator.configure ( String configFilename) :读取使用Java的特性文件编写的配置文件。
  DOMConfigurator.configure ( String filename ) :读取XML形式的配置文件。

  3.插入记录信息(格式化日志信息)

  当上两个必要步骤执行完毕,您就可以轻松地使用不同优先级别的日志记录语句插入到您想记录日志的任何地方,其语法如下:

  Logger.debug ( Object message ) ;
  Logger.info ( Object message ) ;
  Logger.warn ( Object message ) ;
  Logger.error ( Object message ) ;

6月13日

表单验证

//file: check.js

//校验是否全由数字组成
function isDigit(s)
{
var patrn=/^[0-9]{1,20}$/;
if (!patrn.exec(s)) return false
return true
}

//校验登录名:只能输入5-20个以字母开头、可带数字、“_”、“.”的字串
function isRegisterUserName(s)
{
var patrn=/^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){4,19}$/;
if (!patrn.exec(s)) return false
return true
}

//校验用户姓名:只能输入1-30个以字母开头的字串
function isTrueName(s)
{
var patrn=/^[a-zA-Z]{1,30}$/;
if (!patrn.exec(s)) return false
return true
}

//校验密码:只能输入6-20个字母、数字、下划线
function isPasswd(s)
{
var patrn=/^(\w){6,20}$/;
if (!patrn.exec(s)) return false
return true
}

//校验普通电话、传真号码:可以“+”开头,除数字外,可含有“-”
function isTel(s)
{
//var patrn=/^[+]{0,1}(\d){1,3}[ ]?([-]?(\d){1,12})+$/;
var patrn=/^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$/;
if (!patrn.exec(s)) return false
return true
}

//校验手机号码:必须以数字开头,除数字外,可含有“-”
function isMobil(s)
{
var patrn=/^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$/;
if (!patrn.exec(s)) return false
return true
}

//校验邮政编码
function isPostalCode(s)
{
//var patrn=/^[a-zA-Z0-9]{3,12}$/;
var patrn=/^[a-zA-Z0-9 ]{3,12}$/;
if (!patrn.exec(s)) return false
return true
}

//邮件检测
function isEmail(theStr) {

var atIndex = theStr.indexOf('@');
var dotIndex = theStr.indexOf('.', atIndex);
var flag = true;
theSub = theStr.substring(0, dotIndex+1)

if ((atIndex < 1)||(atIndex != theStr.lastIndexOf('@'))||(dotIndex < atIndex + 2)||(theStr.length <= theSub.length))
{ return(false); }
else { return(true); }
}
//判断是否为空
function isEmpty (str) {
if ((str==null)||(str.length==0)) return true;
else return(false);
}

//判断日期
function isDate(theStr) {
 var the1st = theStr.indexOf('-');
 var the2nd = theStr.lastIndexOf('-');
 
 if (the1st == the2nd) {
   return false;
 } else {
  var y = theStr.substring(0,the1st);
  var m = theStr.substring(the1st+1,the2nd);
  var d = theStr.substring(the2nd+1,theStr.length);
  var maxDays = 31;
 
  if (isInt(m)==false || isInt(d)==false || isInt(y)==false) {
   return false;
  } else if (y.length < 4) {
    return false ;
  } else if (!isBetween (m, 1, 12)) {
   return false;
  } else if (m==4 || m==6 || m==9 || m==11) {
   maxDays = 30;
  } else if (m==2) {
   if (y % 4 > 0) {
    maxDays = 28;
   }else if (y % 100 == 0 && y % 400 > 0) {
    maxDays = 28;
   }else{
     maxDays = 29;
   }
  }
  if (isBetween(d, 1, maxDays) == false) {
   return false;
  }
  else { return true; }
 }
}

//判断范围
function isBetween (val, lo, hi) {
if ((val < lo) || (val > hi)) { return(false); }
else { return(true); }
}

//判断是否为Int型
function isInt (theStr) {
var flag = true;

if (isEmpty(theStr)) { flag=false; }
else
{ for (var i=0; i<theStr.length; i++) {
if (isDigit(theStr.substring(i,i+1)) == false) {
flag = false; break;
}
}
}
return(flag);
}

//表单元素通用验证方法
//NU  检测是否为空
//NM  检测是否为数字
//EM  检测是否为MAIL
//LE=12  检测长度
//YY  年份
//MM  月份
//DD  日
function validateForm(add){
 var alertMessage = "";
 var elArr = eval(document.forms[0].name).elements;
 var strYY = "";
 var strMM = "";
 var strDD = "";
 for(var i = 0; i < elArr.length; i++){
  if(elArr[i].id){
    var aryList = (elArr[i].id).split(',');
    for(var j=0; j<aryList.length; j++){
       if(aryList[j].substring(0,2) == "NU"){
        if(elArr[i].value==""){
         alertMessage =  alertMessage + elArr[i].title + "不能为空!\n";
         break;
        }
       }
       if(aryList[j].substring(0,2) == "NM"){
        if(elArr[i].value !=""){
        if(isDigit(elArr[i].value)==false){
         alertMessage = alertMessage + elArr[i].title + "不为数字!\n";
         break;
        }
       }
       }
       if(aryList[j].substring(0,2) == "EM"){
        if(elArr[i].value !=""){
        if(isEmail(elArr[i].value)==false){
           
         alertMessage = alertMessage + elArr[i].title + "格式有误!\n";
         break;
        }
       }
       }
       if(aryList[j].substring(0,2) == "LE"){
        if(elArr[i].value !=""){
         var eleLength = elArr[i].value.length;
         var ordLength = aryList[j].substring(3,100);
        if( eleLength > ordLength){
         alertMessage = alertMessage + elArr[i].title + "长度要求为"+ ordLength +"位!\n";
         break;
        }
       } 
       } 
       if(aryList[j].substring(0,2) == "YY"){
    strYY = elArr[i].value;
       } 
       if(aryList[j].substring(0,2) == "MM"){
    strMM = elArr[i].value;
       }
       if(aryList[j].substring(0,2) == "DD"){
    strDD = elArr[i].value;
       }
       if(strYY != "" && strMM != "" && strDD != ""){
        if(strYY != "" && strMM != "" && strDD != ""){
        var strDate = strYY + "-" + strMM +"-"+ strDD;
        if(isDate(strDate) == false){
         alertMessage = alertMessage + "日期格式不正确\n";
         strYY = "";
         strMM = "";
         strDD = "";
        }
       }
       }
      
    }
  }
 }
 
 if(add == "true"){
  alertMessage =  addMessage(alertMessage);
 }
 
 if(alertMessage != ""){
  alert(alertMessage);
  return false;
 }else{
  return true;
 }
}


function checkboxChecked(checkboxName)
{    
    var count=0;
    var formname = document.forms[0].name;
    if(eval("document." + formname + "." + checkboxName).length!=null)
    {     
     
        for (var i = 0; i < eval("document." + formname + "." + checkboxName).length; i++)      
        {
     if (eval("document." + formname + "." + checkboxName)[i].checked == true)
     {
      
         count=count+1;
     }
        }
    }
    else
    {   
        if (eval("document." + formname + "." + checkboxName).checked == true)
        {
     count=count+1;
        }
    }  
    return count;
}

//file: index.html 

<html>
<script language="JavaScript" src="check.js"></script>
<script>
function addMessage(message){
 message = message + "另加的错误信息\n"
 return message;
}
</script>
<body>
<form name="ordForm" id="ordForm" method="post">
<input type="test" name="name"      id="NU,NM"    title="姓名">
<input type="test" name="password"  id="NU,LE=12"    title="密码">
<input type="test" name="mail"      id="NU,EM"    title="邮件">
<input type="test" name="yyBIRTHDAY"        id="YY"    title="姓名">
<input type="test" name="mmBIRTHDAY"        id="MM"    title="密码">
<input type="test" name="ddBIRTHDAY"        id="DD"    title="邮件">
<input type="button" value="submit" onClick="validateForm(ordForm)">
</form>
</body>
</html>

//表单元素通用验证方法
//NU  检测是否为空
//NM  检测是否为数字
//EM  检测是否为MAIL
//LE=12  检测长度
//YY  年份
//MM  月份
//DD  日

下拉框三级联动

<HTML>
<HEAD>
<META http-equiv='Content-Type' content='text/html; charset=gb2312'>
<TITLE>一个经典的下拉框三级联动,并链接到相应站点</TITLE>
</HEAD>
<BODY >

<FORM name="isc">
<table border="0" cellspacing="0" cellpadding="0">
  <tr align="center">
    <td nowrap height="11"> &nbsp;

<select name="example" size="1" onChange="redirect(this.options.selectedIndex)">
<option selected>---Select1-------------</option>
<option>Webmaster Sites</option>
<option>News Sites</option>
</select>

<select name="stage2" size="1" onChange="redirect1(this.options.selectedIndex)">
<option value=" " selected> </option>
<option value=" " selected>---Select2--------------</option>
<option value=" " selected>---Select2--------------</option>
</select>

<select name="stage3" size="1" onChange="redirect2(this.options.selectedIndex)">
<option value=" " selected> </option>
<option value=" " selected>---Select3----------------</option>
<option value=" " selected>---Select3----------------</option>
</select>

<script>

var groups=document.isc.example.options.length
var group=new Array(groups)
for (i=0; i<groups; i++)
group[i]=new Array()

group[0][0]=new Option("---Select2---"," ");

group[1][0]=new Option("Now Select This One"," ");
group[1][1]=new Option("JavaScript","47");
group[1][2]=new Option("DHTML","46");
group[1][3]=new Option("CGI","45");

group[2][0]=new Option("Now Select This One"," ");
group[2][1]=new Option("General News","115");
group[2][2]=new Option("Technology News","116");

var temp=document.isc.stage2


function redirect(x){
for (m=temp.options.length-1;m>0;m--)
temp.options[m]=null
for (i=0;i<group[x].length;i++){
temp.options[i]=new Option(group[x][i].text,group[x][i].value)
}
temp.options[0].selected=true
redirect1(0)
}

 

var secondGroups=document.isc.stage2.options.length
var secondGroup=new Array(groups)
for (i=0; i<groups; i++)  {
secondGroup[i]=new Array(group[i].length)
for (j=0; j<group[i].length; j++)  {
secondGroup[i][j]=new Array()  }}

secondGroup[0][0][0]=new Option("---Select 3---"," ");
secondGroup[1][0][0]=new Option("---Select 3---"," ");
secondGroup[1][1][0]=new Option("Now Select This One"," ");
secondGroup[1][1][1]=new Option("Website Abstraction","http://wsabstract.com");
secondGroup[1][1][2]=new Option("JavaScript for the non programmer","http://webteacher.com/javascript/");
secondGroup[1][1][3]=new Option("Java-Scripts.net","http://java-scripts.net");

secondGroup[1][2][0]=new Option("Now Select This One"," ");
secondGroup[1][2][1]=new Option("Dynamic Drive","http://www.dynamicdrive.com");
secondGroup[1][2][2]=new Option("Beginner\'s Guide to DHTML","http://www.geocities.com/ResearchTriangle/Facility/4490/");
secondGroup[1][2][3]=new Option("Web Coder","http://webcoder.com/");

secondGroup[1][3][0]=new Option("Now Select This One"," ");
secondGroup[1][3][1]=new Option("CGI Resources","http://www.cgi-resources.com");
secondGroup[1][3][2]=new Option("Ada\'s Intro to CGI","http://adashimar.hypermart.net/");

secondGroup[2][0][0]=new Option("---Select 3---"," ");
secondGroup[2][1][0]=new Option("Now Select This One"," ");
secondGroup[2][1][1]=new Option("CNN","http://www.cnn.com");
secondGroup[2][1][2]=new Option("MSNBC","http://www.msnbc.com");
secondGroup[2][1][3]=new Option("ABC News","http://www.abcnews.com");

secondGroup[2][2][0]=new Option("Now Select A Page"," ");
secondGroup[2][2][1]=new Option("News.com","http://www.news.com");
secondGroup[2][2][2]=new Option("Wired","http://www.wired.com");

var temp1=document.isc.stage3
function redirect1(y){
for (m=temp1.options.length-1;m>0;m--)
temp1.options[m]=null
for (i=0;i<secondGroup[document.isc.example.options.selectedIndex][y].length;i++){
temp1.options[i]=new Option(secondGroup[document.isc.example.options.selectedIndex][y][i].text,secondGroup[document.isc.example.options.selectedIndex][y][i].value)
}
temp1.options[0].selected=true
}

function redirect2(z){
window.location=temp1[z].value
}

</script>

  </td>
  </tr>
</table>
</FORM>


</BODY></HTML>

6月10日

Javascript 表单之间的数据传递

  今天有朋友问我关于用JAVASCRIPT来进行页面各表单之间的数据传递的问题,我以前也写过,不过从来没有注意,今天总结了一下,希望能够给大家一些帮助,也帮助我总结以前学过,用过的知识。

  一,最简单的就是同一个网页里的表单的数据传递。

  举个实例,一个网页上有两个表单,每个表单里一个文本框,一个按钮。点按钮互相对操作对方的文本框的值。我们举的例子是把一个文本框付给另一个文本框。具体的HTML代码如下:

<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>

<form name="form1" method="post" action="">
  <input type="text" name="textfield">
  <input type="button" name="Submit" value="1---------&gt;2" onClick="ok()">
</form>

<form name="form2" method="post" action="">
  <input type="text" name="textfield2">
  <input type="button" name="Submit" value="2-----&gt;1" onClick="ok1()">
</form>

</body>
</html>

以上为HTMl的代码,大家可能注意到了onclik的代码了,有两个函数,接下来就是JAVASCRIPT的代码了:

<script language="JavaScript">
function ok()
{
  document.form2.textfield2.value=document.form1.textfield.value;
}
function ok1()
{
document.form1.textfield.value=document.form2.textfield2.value;
}
</script>

二,第二种是两个窗口之间的表单的文本框之间数据传递。其实这个可以在原来的基础上进行一些扩展就可以了。关于如何创建弹出窗口,窗体里的表单的代码, 在这里就不多说了,现在在这里说一下如何操作父窗口的表单里的文本框的数据。具体代码如下:

<script language="JavaScript">
function ok()
{
 opener.document.form2.textfield2.value=document.form1.textfield.value
}
</script>

三,第三种就是框架网页之间的表单的文本框之间数据传递.
        注意的地方是框架的写法:

<frameset cols="505,505">
  <frame src="test.htm" name="leftr" id="leftr">//定义框架的名称
  <frame src="test2.htm" id="right" name="right">
</frameset>
<noframes><body>

</body></noframes>

 具体的实现代码如下:

<script language="JavaScript">
function ok()
{
 parent.leftr.document.form2.textfield2.value
 =document.form1.textfield.value
}
</script>

  这三种窗口之间的文本框数值互相操作的简单方法就实现了,其它需要注意的就是他们之间的关系。

  其实很简单的,现丑了,希望大家互相交流,QQ:171476439。

40种网页常用小技巧

1. oncontextmenu="window.event.returnValue=false" 将彻底屏蔽鼠标右键
<table border oncontextmenu=return(false)><td>no</table> 可用于Table

2. <body onselectstart="return false"> 取消选取、防止复制

3. onpaste="return false" 不准粘贴

4. oncopy="return false;" oncut="return false;" 防止复制

5. <link rel="Shortcut Icon" href="favicon.ico"> IE地址栏前换成自己的图标

6. <link rel="Bookmark" href="favicon.ico"> 可以在收藏夹中显示出你的图标

7. <input style="ime-mode:disabled"> 关闭输入法

8. 永远都会带着框架
<script language="JavaScript"><!--
if (window == top)top.location.href = "frames.htm"; //frames.htm为框架网页
// --></script>

9. 防止被人frame
<SCRIPT LANGUAGE=JAVASCRIPT><!-- 
if (top.location != self.location)top.location=self.location;
// --></SCRIPT>

10. 网页将不能被另存为
<noscript><iframe src=*.html></iframe></noscript> 

11. <input type=button value=查看网页源代码 
onclick="window.location = "view-source:"+ "http://www.pconline.com.cn"">

12.删除时确认
<a href="javascript:if(confirm("确实要删除吗?"))location="boos.asp?&areyou=删除&page=1"">删除</a> 

13. 取得控件的绝对位置
//Javascript
<script language="Javascript">
function getIE(e){
var t=e.offsetTop;
var l=e.offsetLeft;
while(e=e.offsetParent){
t+=e.offsetTop;
l+=e.offsetLeft;
}
alert("top="+t+"/nleft="+l);
}
</script>

//VBScript
<script language="VBScript"><!--
function getIE()
dim t,l,a,b
set a=document.all.img1
t=document.all.img1.offsetTop
l=document.all.img1.offsetLeft
while a.tagName<>"BODY"
set a = a.offsetParent
t=t+a.offsetTop
l=l+a.offsetLeft
wend
msgbox "top="&t&chr(13)&"left="&l,64,"得到控件的位置"
end function
--></script>

14. 光标是停在文本框文字的最后
<script language="javascript">
function cc()
{
var e = event.srcElement;
var r =e.createTextRange();
r.moveStart("character",e.value.length);
r.collapse(true);
r.select();
}
</script>
<input type=text name=text1 value="123" onfocus="cc()">

15. 判断上一页的来源
javascript:
document.referrer

16. 最小化、最大化、关闭窗口
<object id=hh1 classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11"> 
<param name="Command" value="Minimize"></object>
<object id=hh2 classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11"> 
<param name="Command" value="Maximize"></object>
<OBJECT id=hh3 classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11">
<PARAM NAME="Command" VALUE="Close"></OBJECT>
<input type=button value=最小化 onclick=hh1.Click()>
<input type=button value=最大化 onclick=hh2.Click()>
<input type=button value=关闭 onclick=hh3.Click()>
本例适用于IE

17.屏蔽功能键Shift,Alt,Ctrl
<script>
function look(){ 
if(event.shiftKey) 
alert("禁止按Shift键!"); //可以换成ALT CTRL

document.onkeydown=look; 
</script>

18. 网页不会被缓存
<META HTTP-EQUIV="pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate">
<META HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1997 08:21:57 GMT">
或者<META HTTP-EQUIV="expires" CONTENT="0">

19.怎样让表单没有凹凸感?
<input type=text style="border:1 solid #000000"> 

<input type=text style="border-left:none; border-right:none; border-top:none; border-bottom: 

1 solid #000000"></textarea>

20.<div><span>&<layer>的区别? 
<div>(division)用来定义大段的页面元素,会产生转行 
<span>用来定义同一行内的元素,跟<div>的唯一区别是不产生转行 
<layer>是ns的标记,ie不支持,相当于<div>

21.让弹出窗口总是在最上面:
<body onblur="this.focus();">

22.不要滚动条? 
让竖条没有: 
<body style="overflow:scroll;overflow-y:hidden"> 
</body> 
让横条没有: 
<body style="overflow:scroll;overflow-x:hidden"> 
</body> 
两个都去掉?更简单了 
<body scroll="no"> 
</body> 

23.怎样去掉图片链接点击后,图片周围的虚线?
<a href="#" onFocus="this.blur()"><img src="logo.jpg" border=0></a>

24.电子邮件处理提交表单
<form name="form1" method="post" action="mailto:****@***.com" enctype="text/plain"> 
<input type=submit>
</form>

25.在打开的子窗口刷新父窗口的代码里如何写?
window.opener.location.reload()

26.如何设定打开页面的大小
<body onload="top.resizeTo(300,200);">
打开页面的位置<body onload="top.moveBy(300,200);">

27.在页面中如何加入不是满铺的背景图片,拉动页面时背景图不动 
<STYLE> 
body 
{background-image:url(logo.gif); background-repeat:no-repeat; 
background-position:center;background-attachment: fixed} 
</STYLE> 

28. 检查一段字符串是否全由数字组成
<script language="Javascript"><!--
function checkNum(str){return str.match(//D/)==null}
alert(checkNum("1232142141"))
alert(checkNum("123214214a1"))
// --></script>

29. 获得一个窗口的大小
document.body.clientWidth; document.body.clientHeight

30. 怎么判断是否是字符
if (/[^/x00-/xff]/g.test(s)) alert("含有汉字");
else alert("全是字符");

31.TEXTAREA自适应文字行数的多少
<textarea rows=1 name=s1 cols=27 onpropertychange="this.style.posHeight=this.scrollHeight">
</textarea>
32. 日期减去天数等于第二个日期
<script language=Javascript>
function cc(dd,dadd)
{
//可以加上错误处理
var a = new Date(dd)
a = a.valueOf()
a = a - dadd * 24 * 60 * 60 * 1000
a = new Date(a)
alert(a.getFullYear() + "年" + (a.getMonth() + 1) + "月" + a.getDate() + "日")
}
cc("12/23/2002",2)
</script>

33. 选择了哪一个Radio
<HTML><script language="vbscript">
function checkme()
for each ob in radio1
if ob.checked then window.alert ob.value
next
end function
</script><BODY>
<INPUT name="radio1" type="radio" value="style" checked>Style
<INPUT name="radio1" type="radio" value="barcode">Barcode
<INPUT type="button" value="check" onclick="checkme()">
</BODY></HTML>

34.脚本永不出错
<SCRIPT LANGUAGE="JavaScript"> 
<!-- Hide 
function killErrors() { 
return true; 

window.onerror = killErrors; 
// --> 
</SCRIPT>

35.ENTER键可以让光标移到下一个输入框
<input onkeydown="if(event.keyCode==13)event.keyCode=9">

36. 检测某个网站的链接速度:
把如下代码加入<body>区域中:
<script language=Javascript>
tim=1
setInterval("tim++",100)
b=1
var autourl=new Array()
autourl[1]="www.njcatv.net"
autourl[2]="javacool.3322.net"
autourl[3]="www.sina.com.cn"
autourl[4]="www.nuaa.edu.cn"
autourl[5]="www.cctv.com"
function butt(){
document.write("<form name=autof>")
for(var i=1;i<autourl.length;i++)
document.write("<input type=text name=txt"+i+" size=10 value=测试中……> =》<input type=text 
name=url"+i+" size=40> =》<input type=button value=GO 

onclick=window.open(this.form.url"+i+".value)><br>")
document.write("<input type=submit value=刷新></form>")
}
butt()
function auto(url){
document.forms[0]["url"+b].value=url
if(tim>200)
{document.forms[0]["txt"+b].value="链接超时"}
else
{document.forms[0]["txt"+b].value="时间"+tim/10+"秒"}
b++
}
function run(){for(var i=1;i<autourl.length;i++)document.write("<img src=http://"+autourl+"/"+Math.random()+" width=1 height=1 

onerror=auto("http://"+autourl+"")>")}
run()</script>

37. 各种样式的光标
auto :标准光标
default :标准箭头
hand :手形光标
wait :等待光标
text :I形光标
vertical-text :水平I形光标
no-drop :不可拖动光标
not-allowed :无效光标
help :?帮助光标
all-scroll :三角方向标
move :移动标
crosshair :十字标
e-resize
n-resize
nw-resize
w-resize
s-resize
se-resize
sw-resize

38.页面进入和退出的特效
进入页面<meta http-equiv="Page-Enter" content="revealTrans(duration=x, transition=y)">
推出页面<meta http-equiv="Page-Exit" content="revealTrans(duration=x, transition=y)"> 
这个是页面被载入和调出时的一些特效。duration表示特效的持续时间,以秒为单位。transition表示使用哪种特效,取值为1-23:
  0 矩形缩小 
  1 矩形扩大 
  2 圆形缩小
  3 圆形扩大 
  4 下到上刷新 
  5 上到下刷新
  6 左到右刷新 
  7 右到左刷新 
  8 竖百叶窗
  9 横百叶窗 
  10 错位横百叶窗 
  11 错位竖百叶窗
  12 点扩散 
  13 左右到中间刷新 
  14 中间到左右刷新
  15 中间到上下
  16 上下到中间 
  17 右下到左上
  18 右上到左下 
  19 左上到右下 
  20 左下到右上
  21 横条 
  22 竖条 
  23 以上22种随机选择一种

39.在规定时间内跳转
<META http-equiv=V="REFRESH" content="5;URL=http://www.51js.com"> 

40.网页是否被检索
<meta name="ROBOTS" content="属性值">
  其中属性值有以下一些:
  属性值为"all": 文件将被检索,且页上链接可被查询;
  属性值为"none": 文件不被检索,而且不查询页上的链接;
  属性值为"index": 文件将被检索;
  属性值为"follow": 查询页上的链接;
  属性值为"noindex": 文件不检索,但可被查询链接;
  属性值为"nofollow": 文件不被检索,但可查询页上的链接。