Luben Park

          Java Ben 成長之路

          2006年2月17日 #

          表名作為參數(shù)傳遞的存儲過程寫法

          SET QUOTED_IDENTIFIER ON
          GO
          SET ANSI_NULLS ON
          GO

          ?

          --=================================================================
          -- 描述:~~~~~~~~~~~~~~~~~~~~~~~~~~~
          -- 作者:魯湘
          -- @tableName?? 該模板對應(yīng)的數(shù)據(jù)庫表
          -- @RecordID??? 業(yè)務(wù)處理需要尋找表中記錄的ID號碼
          --=================================================================

          ALTER??? PROCEDURE WF_QingJia
          ? ?(@tableName varchar(50),@recordID varchar(50))
          AS
          -- 獲取表中的業(yè)務(wù)數(shù)據(jù)值
          DECLARE @money varchar(100),? -- 業(yè)務(wù)邏輯需要的值
          ?@sqls nvarchar(4000)? -- 保存組合SQL語句

          SET @sqls='SELECT @a=Money FROM '+@tableName +' WHERE ID ='+@recordID

          EXECUTE sp_executesql @sqls,N'@a varchar(50) output',@money output

          -- 根據(jù)值進(jìn)行相應(yīng)的業(yè)務(wù)處理
          print @money
          UPDATE WF_FormBill SET [Money]='真的被處理了' WHERE [ID]=@recordID

          ?

          GO
          SET QUOTED_IDENTIFIER OFF
          GO
          SET ANSI_NULLS ON
          GO

          posted @ 2006-11-16 16:49 Ben 閱讀(962) | 評論 (0)編輯 收藏

          [轉(zhuǎn)]經(jīng)典SQL語句--收藏 http://blog.ourtw.com/article.php?tid_600.html

          經(jīng)典SQL語句--收藏
          [個人收藏]經(jīng)典SQL語句.值得收藏
          精典的SQL語句,推薦收藏
          在網(wǎng)上經(jīng)常轉(zhuǎn),常常看到有些人為了求得某些SQL語句而焦頭爛額,現(xiàn)在我特別把自己收藏的一些比較精典的SQL拿出來和大家分享一下

          1. 行列轉(zhuǎn)換--普通

          假設(shè)有張學(xué)生成績表(CJ)如下
          Name ? Subject ? Result
          張三 ? 語文 ? ? 80
          張三 ? 數(shù)學(xué) ? ? 90
          張三 ? 物理 ? ? 85
          李四 ? 語文 ? ? 85
          李四 ? 數(shù)學(xué) ? ? 92
          李四 ? 物理 ? ? 82

          想變成 ?
          姓名 ? 語文 ? 數(shù)學(xué) ? 物理
          張三 ? 80 ? 90 ? 85
          李四 ? 85 ? 92 ? 82

          declare @sql varchar(4000)
          set @sql = ''select Name''
          select @sql = @sql + '',sum(case Subject when ''''''+Subject+'''''' then Result end) [''+Subject+'']''
          from (select distinct Subject from CJ) as a
          select @sql = @sql+'' from test group by name''
          exec(@sql)

          2. 行列轉(zhuǎn)換--合并

          有表A,
          id pid
          1 ? 1
          1 ? 2
          1 ? 3
          2 ? 1
          2 ? 2
          3 ? 1
          如何化成表B:
          id pid
          1 1,2,3
          2 1,2
          3 1

          創(chuàng)建一個合并的函數(shù)
          create function fmerg(@id int)
          returns varchar(8000)
          as
          begin
          declare @str varchar(8000)
          set @str=''''
          select @str=@str+'',''+cast(pid as varchar) from 表A where id=@id set @str=right(@str,len(@str)-1)
          return(@str)
          End
          go

          --調(diào)用自定義函數(shù)得到結(jié)果
          select distinct id,dbo.fmerg(id) from 表A

          3. 如何取得一個數(shù)據(jù)表的所有列名

          方法如下:先從SYSTEMOBJECT系統(tǒng)表中取得數(shù)據(jù)表的SYSTEMID,然后再SYSCOLUMN表中取得該數(shù)據(jù)表的所有列名。
          SQL語句如下:
          declare @objid int,@objname char(40)
          set @objname = ''tablename''
          select @objid = id from sysobjects where id = object_id(@objname)
          select ''Column_name'' = name from syscolumns where id = @objid order by colid

          是不是太簡單了? 呵呵 不過經(jīng)常用阿.

          4. 通過SQL語句來更改用戶的密碼

          修改別人的,需要sysadmin role ?
          EXEC sp_password NULL, ''newpassword'', ''User''

          如果帳號為SA執(zhí)行EXEC sp_password NULL, ''newpassword'', sa

          5. 怎么判斷出一個表的哪些字段不允許為空?

          select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where IS_NULLABLE=''NO'' and TABLE_NAME=tablename

          6. 如何在數(shù)據(jù)庫里找到含有相同字段的表?
          a. 查已知列名的情況
          SELECT b.name as TableName,a.name as columnname
          From syscolumns ? a INNER JOIN ? sysobjects b ?
          ON a.id=b.id ?
          AND b.type=''U'' ?
          AND a.name=''你的字段名字''

          b. 未知列名查所有在不同表出現(xiàn)過的列名
          Select o.name As tablename,s1.name As columnname
          From syscolumns s1, sysobjects o
          Where s1.id = o.id
          ? And o.type = ''U''
          ? And Exists (
          ? ? Select 1 From syscolumns s2 ?
          ? ? Where s1.name = s2.name ?
          ? ? And s1.id <> s2.id
          ? ? )

          7. 查詢第xxx行數(shù)據(jù)

          假設(shè)id是主鍵:
          select *
          from (select top xxx * from yourtable) aa
          where not exists(select 1 from (select top xxx-1 * from yourtable) bb where aa.id=bb.id)

          如果使用游標(biāo)也是可以的
          fetch absolute [number] from [cursor_name]
          行數(shù)為絕對行數(shù)

          8. SQL Server日期計算
          a. 一個月的第一天
          SELECT DATEADD(mm, DATEDIFF(mm,0,getdate()), 0)
          b. 本周的星期一
          SELECT DATEADD(wk, DATEDIFF(wk,0,getdate()), 0)
          c. 一年的第一天
          SELECT DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)
          d. 季度的第一天
          SELECT DATEADD(qq, DATEDIFF(qq,0,getdate()), 0)
          e. 上個月的最后一天
          SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()), 0))
          f. 去年的最后一天
          SELECT dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0))
          g. 本月的最后一天
          SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,getdate())+1, 0))
          h. 本月的第一個星期一
          select DATEADD(wk, DATEDIFF(wk,0, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
          ? ? ? ? ? ? ? ? ? ? dateadd(dd,6-datepart(day,getdate()),getdate()) ? ?
          ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ), 0) ? ?
          i. 本年的最后一天
          SELECT dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate())+1, 0))。
          -----------------------------------------------------------------------
          1.按姓氏筆畫排序:
          Select * From TableName Order By CustomerName Collate Chinese_PRC_Stroke_ci_as

          2.數(shù)據(jù)庫加密:
          select encrypt(''原始密碼'')
          select pwdencrypt(''原始密碼'')
          select pwdcompare(''原始密碼'',''加密后密碼'') = 1--相同;否則不相同 encrypt(''原始密碼'')
          select pwdencrypt(''原始密碼'')
          select pwdcompare(''原始密碼'',''加密后密碼'') = 1--相同;否則不相同

          3.取回表中字段:
          declare @list varchar(1000),@sql nvarchar(1000)
          select @list=@list+'',''+b.name from sysobjects a,syscolumns b where a.id=b.id and a.name=''表A''
          set @sql=''select ''+right(@list,len(@list)-1)+'' from 表A''
          exec (@sql)

          4.查看硬盤分區(qū):
          EXEC master..xp_fixeddrives

          5.比較A,B表是否相等:
          if (select checksum_agg(binary_checksum(*)) from A)
          ? =
          ? (select checksum_agg(binary_checksum(*)) from B)
          print ''相等''
          else
          print ''不相等''

          6.殺掉所有的事件探察器進(jìn)程:
          DECLARE hcforeach CURSOR GLOBAL FOR SELECT ''kill ''+RTRIM(spid) FROM master.dbo.sysprocesses
          WHERE program_name IN(''SQL profiler'',N''SQL 事件探查器'')
          EXEC sp_msforeach_worker ''?''

          7.記錄搜索:
          開頭到N條記錄
          Select Top N * From 表
          -------------------------------
          N到M條記錄(要有主索引ID)
          Select Top M-N * From 表 Where ID in (Select Top M ID From 表) Order by ID Desc
          ----------------------------------
          N到結(jié)尾記錄
          Select Top N * From 表 Order by ID Desc

          8.如何修改數(shù)據(jù)庫的名稱:
          sp_renamedb ''old_name'', ''new_name''

          9:獲取當(dāng)前數(shù)據(jù)庫中的所有用戶表
          select Name from sysobjects where xtype=''u'' and status>=0

          10:獲取某一個表的所有字段
          select name from syscolumns where id=object_id(''表名'')

          11:查看與某一個表相關(guān)的視圖、存儲過程、函數(shù)
          select a.* from sysobjects a, syscomments b where a.id = b.id and b.text like ''%表名%''

          12:查看當(dāng)前數(shù)據(jù)庫中所有存儲過程
          select name as 存儲過程名稱 from sysobjects where xtype=''P''

          13:查詢用戶創(chuàng)建的所有數(shù)據(jù)庫
          select * from master..sysdatabases D where sid not in(select sid from master..syslogins where name=''sa'')
          或者
          select dbid, name AS DB_NAME from master..sysdatabases where sid <> 0x01

          14:查詢某一個表的字段和數(shù)據(jù)類型
          select column_name,data_type from information_schema.columns
          where table_name = ''表名''

          [n].[標(biāo)題]:
          Select * From TableName Order By CustomerName

          [n].[標(biāo)題]:
          Select * From TableName Order By CustomerName

          posted @ 2006-04-06 15:01 Ben 閱讀(884) | 評論 (0)編輯 收藏

          vs2003 和vs2005下的發(fā)送SMTP郵件 (downmoon原創(chuàng)) 選擇自 downmoon 的 Blog

          vs2003 和vs2005下的發(fā)送SMTP郵件 (downmoon原創(chuàng))
          一、vs2003
          引用 System.Web.Mail命名空間

          ?private void SenMail2003()
          ??? {
          ??????? MailMessage mailObj = new MailMessage();
          ??????? mailObj.To = this.txtTo.Text;
          ??????? mailObj.From = this.txtFrom.Text;
          ???????
          ??????? mailObj.Subject = "精采笑話";
          ??????? mailObj.Body = "豬!你已中毒! 哈哈 ";
          ???????
          ??????? mailObj.BodyFormat = MailFormat.Html;
          ??????? mailObj.BodyEncoding = MailFormat.Base64;
          ??????? mailObj.Priority = MailPriority.High;
          ??????? mailObj.Attachments.Add(new MailAttachment("c:\\swf\\000.bmp"));
          ??????? SmtpMail.Send(mailObj);
          ??????? Response.Write("發(fā)送郵件成功!");
          ??? }

          二、vs2005
          引用 System.Net.Mail命名空間,安全性得到了增強

          ?public static void SendWebMailAndAttach(string server)
          ??? {
          ???????? string file = "e:\\inetpub\\wwwroot\\Test2005All\\TestXML\\testXML.xml";
          ???????? System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage("Test@126.com", "Test@126.com", "text message for you.", "Test Title");
          ???????? System.Net.Mail.Attachment data = new System.Net.Mail.Attachment(file, System.Net.Mime.MediaTypeNames.Application.Octet);
          ???????? System.Net.Mime.ContentDisposition disposition = data.ContentDisposition;
          ???????? disposition.CreationDate = System.IO.File.GetCreationTime(file);
          ???????? disposition.ModificationDate = System.IO.File.GetLastWriteTime(file);
          ???????? disposition.ReadDate = System.IO.File.GetLastAccessTime(file);
          ???????? message.Attachments.Add(data);
          ??????? System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(server);
          ??????? client.Credentials = new NetworkCredential("用戶名", "密碼");
          ??????? client.Send(message);
          ??????? data.Dispose();
          ??? }
          引用示例
          SendWebMailAndAttach("smtp.126.com");

          posted @ 2006-04-06 14:18 Ben 閱讀(472) | 評論 (0)編輯 收藏

          SQL中CONVERT轉(zhuǎn)化函數(shù), Concat , COALESCE的用法

          SQL中CONVERT轉(zhuǎn)化函數(shù)的用法

          CONVERT的使用方法:

          ////////////////////////////////////////////////////////////////////////////////////////

          格式:
          CONVERT(data_type,expression[,style])

          說明:
          此樣式一般在時間類型(datetime,smalldatetime)與字符串類型(nchar,nvarchar,char,varchar)
          相互轉(zhuǎn)換的時候才用到.

          例子:
          SELECT CONVERT(varchar(30),getdate(),101) now
          結(jié)果為
          now
          ---------------------------------------
          09/15/2001

          /////////////////////////////////////////////////////////////////////////////////////

          style數(shù)字在轉(zhuǎn)換時間時的含義如下

          -------------------------------------------------------------------------------------------------
          Style(2位表示年份) | Style(4位表示年份) | 輸入輸出格式
          -------------------------------------------------------------------------------------------------
          - | 0 or 100 | mon dd yyyy hh:miAM(或PM)
          -------------------------------------------------------------------------------------------------
          1 | 101 | mm/dd/yy
          -------------------------------------------------------------------------------------------------
          2 | 102 | yy-mm-dd
          -------------------------------------------------------------------------------------------------
          3 | 103 | dd/mm/yy
          -------------------------------------------------------------------------------------------------
          4 | 104 | dd-mm-yy
          -------------------------------------------------------------------------------------------------
          5 | 105 | dd-mm-yy
          -------------------------------------------------------------------------------------------------
          6 | 106 | dd mon yy
          -------------------------------------------------------------------------------------------------
          7 | 107 | mon dd,yy
          -------------------------------------------------------------------------------------------------
          8 | 108 | hh:mm:ss
          -------------------------------------------------------------------------------------------------
          - | 9 or 109 | mon dd yyyy hh:mi:ss:mmmmAM(或PM)
          -------------------------------------------------------------------------------------------------
          10 | 110 | mm-dd-yy
          -------------------------------------------------------------------------------------------------
          11 | 111 | yy/mm/dd
          -------------------------------------------------------------------------------------------------
          12 | 112 | yymmdd
          -------------------------------------------------------------------------------------------------
          - | 13 or 113 | dd mon yyyy hh:mi:ss:mmm(24小時制)
          -------------------------------------------------------------------------------------------------
          14 | 114 | hh:mi:ss:mmm(24小時制)
          -------------------------------------------------------------------------------------------------
          - | 20 or 120 | yyyy-mm-dd hh:mi:ss(24小時制)
          -------------------------------------------------------------------------------------------------
          - | 21 or 121 | yyyy-mm-dd hh:mi:ss:mmm(24小時制)
          -------------------------------------------------------------------------------------------------

          concat
          方法的結(jié)果等于:result = string1 + string2 + string3 + … + stringN

          COALESCE 返回其參數(shù)中第一個非空表達(dá)式

          posted @ 2006-04-06 14:15 Ben 閱讀(1974) | 評論 (0)編輯 收藏

          [轉(zhuǎn)].NET(C#)連接各類數(shù)據(jù)庫-集錦

          1.C#連接連接Access
          程序代碼:
          -------------------------------------------------------------------------------

          using System.Data;
          using System.Data.OleDb;

          ......

          string strConnection="Provider=Microsoft.Jet.OleDb.4.0;";
          strConnection+=@"Data Source=C:\BegASPNET\Northwind.mdb";

          OleDbConnection objConnection=new OleDbConnection(strConnection);

          ......

          objConnection.Open();
          objConnection.Close();

          ......

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

          解釋:

           連接Access數(shù)據(jù)庫需要導(dǎo)入額外的命名空間,所以有了最前面的兩條using命令,這是必不可少的!

           strConnection這個變量里存放的是連接數(shù)據(jù)庫所需要的連接字符串,他指定了要使用的數(shù)據(jù)提供者和要使用的數(shù)據(jù)源.

           "Provider=Microsoft.Jet.OleDb.4.0;"是指數(shù)據(jù)提供者,這里使用的是Microsoft Jet引擎,也就是Access中的數(shù)據(jù)引擎,asp.net就是靠這個和Access的數(shù)據(jù)庫連接的.

           "Data Source=C:\BegASPNET\Northwind.mdb"是指明數(shù)據(jù)源的位置,他的標(biāo)準(zhǔn)形式是"Data Source=MyDrive:MyPath\MyFile.MDB".

          PS:
           1."+="后面的"@"符號是防止將后面字符串中的"\"解析為轉(zhuǎn)義字符.
           2.如果要連接的數(shù)據(jù)庫文件和當(dāng)前文件在同一個目錄下,還可以使用如下的方法連接:
            strConnection+="Data Source=";
            strConnection+=MapPath("Northwind.mdb");
            這樣就可以省得你寫一大堆東西了!
           3.要注意連接字符串中的參數(shù)之間要用分號來分隔.

           "OleDbConnection objConnection=new OleDbConnection(strConnection);"這一句是利用定義好的連接字符串來建立了一個鏈接對象,以后對數(shù)據(jù)庫的操作我們都要和這個對象打交道.

           "objConnection.Open();"這用來打開連接.至此,與Access數(shù)據(jù)庫的連接完成.
          --------------------------------------------------------------------------------

          2.C#連接SQL Server
          程序代碼:
          --------------------------------------------------------------------------------

          using System.Data;
          using System.Data.SqlClient;

          ...

          string strConnection="user id=sa;password=;";
          strConnection+="initial catalog=Northwind;Server=YourSQLServer;";
          strConnection+="Connect Timeout=30";

          SqlConnection objConnection=new SqlConnection(strConnection);

          ...

          objConnection.Open();
          objConnection.Close();

          ...

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

          解釋:

          連接SQL Server數(shù)據(jù)庫的機制與連接Access的機制沒有什么太大的區(qū)別,只是改變了Connection對象和連接字符串中的不同參數(shù).

          首先,連接SQL Server使用的命名空間不是"System.Data.OleDb",而是"System.Data.SqlClient".

          其次就是他的連接字符串了,我們一個一個參數(shù)來介紹(注意:參數(shù)間用分號分隔):
           "user id=sa":連接數(shù)據(jù)庫的驗證用戶名為sa.他還有一個別名"uid",所以這句我們還可以寫成"uid=sa".
           "password=":連接數(shù)據(jù)庫的驗證密碼為空.他的別名為"pwd",所以我們可以寫為"pwd=".
           這里注意,你的SQL Server必須已經(jīng)設(shè)置了需要用戶名和密碼來登錄,否則不能用這樣的方式來登錄.如果你的SQL Server設(shè)置為Windows登錄,那么在這里就不需要使用"user id"和"password"這樣的方式來登錄,而需要使用"Trusted_Connection=SSPI"來進(jìn)行登錄.
           "initial catalog=Northwind":使用的數(shù)據(jù)源為"Northwind"這個數(shù)據(jù)庫.他的別名為"Database",本句可以寫成"Database=Northwind".
           "Server=YourSQLServer":使用名為"YourSQLServer"的服務(wù)器.他的別名為"Data Source","Address","Addr".如果使用的是本地數(shù)據(jù)庫且定義了實例名,則可以寫為"Server=(local)\實例名";如果是遠(yuǎn)程服務(wù)器,則將"(local)"替換為遠(yuǎn)程服務(wù)器的名稱或IP地址.
           "Connect Timeout=30":連接超時時間為30秒.

           在這里,建立連接對象用的構(gòu)造函數(shù)為:SqlConnection.
          --------------------------------------------------------------------------------

          3.C#連接Oracle
          程序代碼:
          --------------------------------------------------------------------------------

          using System.Data.OracleClient;
          using System.Data;

          //在窗體上添加一個按鈕,叫Button1,雙擊Button1,輸入以下代碼
          private void Button1_Click(object sender, System.EventArgs e)
          {
          string ConnectionString="Data Source=sky;user=system;password=manager;";//寫連接串
          OracleConnection conn=new OracleConnection(ConnectionString);//創(chuàng)建一個新連接
          try
          {
          conn.Open();
          OracleCommand cmd=conn.CreateCommand();

          cmd.CommandText="select * from MyTable";//在這兒寫sql語句
          OracleDataReader odr=cmd.ExecuteReader();//創(chuàng)建一個OracleDateReader對象
          while(odr.Read())//讀取數(shù)據(jù),如果odr.Read()返回為false的話,就說明到記錄集的尾部了???????????????
          {
          Response.Write(odr.GetOracleString(1).ToString());//輸出字段1,這個數(shù)是字段索引,具體怎么使用字段名還有待研究
          }
          odr.Close();
          }
          catch(Exception ee)
          {
          Response.Write(ee.Message); //如果有錯誤,輸出錯誤信息
          }
          finally
          {
          conn.Close(); //關(guān)閉連接
          }
          }

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

          4.C#連接MySQL
          程序代碼:
          --------------------------------------------------------------------------------

          using MySQLDriverCS;

          // 建立數(shù)據(jù)庫連接
          MySQLConnection DBConn;
          DBConn = new MySQLConnection(new MySQLConnectionString("localhost","mysql","root","",3306).AsString);
          DBConn.Open();

          // 執(zhí)行查詢語句
          MySQLCommand DBComm;
          DBComm = new MySQLCommand("select Host,User from user",DBConn);

          // 讀取數(shù)據(jù)
          MySQLDataReader DBReader = DBComm.ExecuteReaderEx();

          // 顯示數(shù)據(jù)
          try
          {
          while (DBReader.Read())
          {
          Console.WriteLine("Host = {0} and User = {1}", DBReader.GetString(0),DBReader.GetString(1));
          }
          }
          finally
          {
          DBReader.Close();
          DBConn.Close();
          }

          //關(guān)閉數(shù)據(jù)庫連接
          DBConn.Close();

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

          5.C#連接IBM DB2
          程序代碼:
          --------------------------------------------------------------------------------

          OleDbConnection1.Open();
          //打開數(shù)據(jù)庫連接
          OleDbDataAdapter1.Fill(dataSet1,"Address");
          //將得來的數(shù)據(jù)填入dataSet
          DataGrid1.DataBind();
          //綁定數(shù)據(jù)
          OleDbConnection1.Close();
          //關(guān)閉連接

          //增加數(shù)據(jù)庫數(shù)據(jù)
          在Web Form上新增對應(yīng)字段數(shù)量個數(shù)的TextBox,及一個button,為該按鍵增加Click響應(yīng)事件代碼如下:

          this.OleDbInsertCommand1.CommandText = "INSERTsintosADDRESS(NAME,
          EMAIL, AGE, ADDRESS) VALUES
          ('"+TextBox1.Text+"','"+TextBox2.Text+"','"+TextBox3.Text+"','"+TextBox4.Text+"')";
          OleDbInsertCommand1.Connection.Open();
          //打開連接
          OleDbInsertCommand1.ExecuteNonQuery();
          //執(zhí)行該SQL語句
          OleDbInsertCommand1.Connection.Close();
          //關(guān)閉連接

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

          6.C#連接SyBase
          程序代碼: (OleDb)
          --------------------------------------------------------------------------------

          Provider=Sybase.ASEOLEDBProvider.2;Initial Catalog=數(shù)據(jù)庫名;User ID=用戶名;Data Source=數(shù)據(jù)源;Extended Properties="";Server Name=ip地址;Network Protocol=Winsock;Server Port Address=5000;

          posted @ 2006-04-05 14:07 Ben 閱讀(317) | 評論 (0)編輯 收藏

          [轉(zhuǎn)帖]SQL Server - [分布式查詢/事務(wù)]

          分布式查詢
          ??? OPENROWSET
          ??? 從Excel取數(shù)據(jù)
          ??? SELECT * FROM OPENROWSET('Microsoft.Jet.OLEDB.4.0','Excel 8.0;Database=d:\1.xls',[Sheet1$])
          ??? 從Oracle取數(shù)據(jù)
          ??? SELECT?* FROM OPENROWSET('MSDAORA.1','NetServiceName';'User';'Password','SELECT * FROM OracleTalbe')
          ?
          ??? Linked Server(for Oracle)
          ??? 建立Linked Server
          ??? sp_addlinkedserver'Allies', 'Oracle', 'MSDAORA.1', 'NetServiceName'
          ??? Oracle的Login
          ??? sp_addlinkedsrvlogin'Allies', FALSE, 'SQLServerLogin', 'OracleUser', 'OraclePassword'
          ??? 從Oracle查詢數(shù)據(jù)
          ??? SELECT*FROM OPENQUERY( Allies, 'SELECT * FROM OracleTalbe'),或者
          ??? SELECT*FROM Allies..OracleUser.OracleTalbe
          ??? 修改Linked Server的Server Option
          ? ?? sp_serveroption'Allies', 'Option Name', 'Option Value'
          ??? 例如
          ??? sp_serveroption'OraDC', 'rpc out', 'true'
          ??? sp_serveroption'OraDC', 'rpc', 'true'
          ??? 向Oracle插入數(shù)據(jù)(還沒有用過)
          ??? INSERT INTO OPENQUERY(Allies, 'SELECT ... FROM OracleTalbe WHERE 1=2') VALUES ( ... )
          ??? 刪除Linked Server
          ??? sp_dropserver'Allies', 'droplogins'
          ?
          ??? 注意:使用OPENROWSET、OPENQUERY時,SQL Server不對提交的SQL語句做任何檢查,直接將語句提交給Linked Server進(jìn)行處理;使用四部分命名法時,SQL Server可能從Linked Server上讀取被引用表的數(shù)據(jù)到SQL Server,然后在SQL Server上來完成其它操作。
          ?
          ??? 設(shè)置SQL Server到Oracle的Linked Server,可參考以下KB文章:
          ??? How to set up and troubleshoot a linked server to Oracle in SQL Server
          ??? Limitations of Microsoft Oracle ODBC Driver and OLEDB Provider
          ??? Techniques to Debug Connectivity Issues to an Oracle Server Using the ODBC Driver and OLE DB Provider
          ??? Supportability of the Microsoft ODBC Driver/ OLE DB Provider for Oracle w.r.t Oracle 8.x
          ?
          ??? 分布式事務(wù)中的OPENROWSET、OPENQUERY、OPENDATASOURCE
          ??? 如果在事務(wù),或是一些隱含使用事務(wù)的情況下,例如TRIGGER中,使用OPENROWSET、OPENQUERY、OPENDATASOURCE時,就需要使用分布式事務(wù)來處理。
          ??? 在分布式事務(wù)中使用OPENROWSET、OPENQUERY、OPENDATASOURCE或Linked Server時,需要注意:
          ??? 1. 必須啟動MSDTC服務(wù)。
          ????Service Name為Distributed Transaction Coodinator。
          ??? 2. 所涉及的Server之間如果存在網(wǎng)關(guān)、防火墻,需要開啟TCP 135端口。
          ??? 分布式事務(wù)需要使用這個端口通訊。
          ??? 3. 如果Server之間跨網(wǎng)段,則Server之間需要能互相PING到機器名(而不是IP地址)。
          ??? 如果相互PING機器名有問題,修改system32/driver/etc目錄下的hosts文件。
          ?
          ??? 上面的設(shè)置不正確時,會出現(xiàn)類似如下的錯誤:
          ??? 該操作未能執(zhí)行,因為 OLE DB 提供程序 'SQLOLEDB' 無法啟動分布式事務(wù)。
          [OLE/DB provider returned message: 新事務(wù)不能登記到指定的事務(wù)處理器中。 ]
          OLE DB 錯誤跟蹤[OLE/DB Provider 'SQLOLEDB' ITransactionJoin::JoinTransaction returned 0x8004d00a]。
          ?
          ?
          ??? 分布式事務(wù)可以查詢下列KB文章:
          ??? Failed to Enlist on Calling Object's Transaction
          ??? How to troubleshoot MS DTC firewall issues
          ??? You receive error 7391 when you run a distributed transaction against a linked server
          ?
          ??? 使用分布式查詢,可以參考:Chapter 25 - Distributed Queries: OLE DB Connectivity
          ??? 關(guān)于ORAOLEDB提供程序的詳細(xì)說明,可以參考:Oracle Provider for OLE DB Developer's Guide - Release 9.2

          posted @ 2006-03-29 16:35 Ben 閱讀(1209) | 評論 (0)編輯 收藏

          [轉(zhuǎn)]揭開正則表達(dá)式的神秘面紗

          [原創(chuàng)文章,轉(zhuǎn)載請保留或注明出處:http://www.regexlab.com/zh/regref.htm]

          引言

              正則表達(dá)式(regular expression)描述了一種字符串匹配的模式,可以用來:(1)檢查一個串中是否含有符合某個規(guī)則的子串,并且可以得到這個子串;(2)根據(jù)匹配規(guī)則對字符串進(jìn)行靈活的替換操作。

              正則表達(dá)式學(xué)習(xí)起來其實是很簡單的,不多的幾個較為抽象的概念也很容易理解。之所以很多人感覺正則表達(dá)式比較復(fù)雜,一方面是因為大多數(shù)的文檔沒有做到由淺入深地講解,概念上沒有注意先后順序,給讀者的理解帶來困難;另一方面,各種引擎自帶的文檔一般都要介紹它特有的功能,然而這部分特有的功能并不是我們首先要理解的。

              文章中的每一個舉例,都可以點擊進(jìn)入到測試頁面進(jìn)行測試。閑話少說,開始。


          1. 正則表達(dá)式規(guī)則

          1.1 普通字符

              字母、數(shù)字、漢字、下劃線、以及后邊章節(jié)中沒有特殊定義的標(biāo)點符號,都是"普通字符"。表達(dá)式中的普通字符,在匹配一個字符串的時候,匹配與之相同的一個字符。

              ,匹配結(jié)果是:成功;匹配到的內(nèi)容是:"c";匹配到的位置是:開始于2,結(jié)束于3。(注:下標(biāo)從0開始還是從1開始,因當(dāng)前編程語言的不同而可能不同)

             
          ,匹配結(jié)果是:成功;匹配到的內(nèi)容是:"bcd";匹配到的位置是:開始于1,結(jié)束于4。


          1.2 簡單的轉(zhuǎn)義字符

              一些不便書寫的字符,采用在前面加 "\" 的方法。這些字符其實我們都已經(jīng)熟知了。

          表達(dá)式

          可匹配

          \r, \n

          代表回車和換行符

          \t

          制表符

          \\

          代表 "\" 本身

              還有其他一些在后邊章節(jié)中有特殊用處的標(biāo)點符號,在前面加 "\" 后,就代表該符號本身。比如:^, $ 都有特殊意義,如果要想匹配字符串中 "^" 和 "$" 字符,則表達(dá)式就需要寫成 "\^" 和 "\$"。

          表達(dá)式

          可匹配

          \^

          匹配 ^ 符號本身

          \$

          匹配 $ 符號本身

          \.

          匹配小數(shù)點(.)本身

              這些轉(zhuǎn)義字符的匹配方法與 "普通字符" 是類似的。也是匹配與之相同的一個字符。

             
          ,匹配結(jié)果是:成功;匹配到的內(nèi)容是:"$d";匹配到的位置是:開始于3,結(jié)束于5。


          1.3 能夠與 '多種字符' 匹配的表達(dá)式

              正則表達(dá)式中的一些表示方法,可以匹配 '多種字符' 其中的任意一個字符。比如,表達(dá)式 "\d" 可以匹配任意一個數(shù)字。雖然可以匹配其中任意字符,但是只能是一個,不是多個。這就好比玩撲克牌時候,大小王可以代替任意一張牌,但是只能代替一張牌。

          表達(dá)式

          可匹配

          \d

          任意一個數(shù)字,0~9 中的任意一個

          \w

          任意一個字母或數(shù)字或下劃線,也就是 A~Z,a~z,0~9,_ 中任意一個

          \s

          包括空格、制表符、換頁符等空白字符的其中任意一個

          .

          小數(shù)點可以匹配除了換行符(\n)以外的任意一個字符

              ,匹配的結(jié)果是:成功;匹配到的內(nèi)容是:"12";匹配到的位置是:開始于3,結(jié)束于5。

             
          ,匹配的結(jié)果是:成功;匹配到的內(nèi)容是:"aa1";匹配到的位置是:開始于1,結(jié)束于4。


          1.4 自定義能夠匹配 '多種字符' 的表達(dá)式

              使用方括號 [ ] 包含一系列字符,能夠匹配其中任意一個字符。用 [^ ] 包含一系列字符,則能夠匹配其中字符之外的任意一個字符。同樣的道理,雖然可以匹配其中任意一個,但是只能是一個,不是多個。

          表達(dá)式

          可匹配

          [ab5@]

          匹配 "a" 或 "b" 或 "5" 或 "@"

          [^abc]

          匹配 "a","b","c" 之外的任意一個字符

          [f-k]

          匹配 "f"~"k" 之間的任意一個字母

          [^A-F0-3]

          匹配 "A"~"F","0"~"3" 之外的任意一個字符

              ,匹配的結(jié)果是:成功;匹配到的內(nèi)容是:"bc";匹配到的位置是:開始于1,結(jié)束于3。

             
          ,匹配的結(jié)果是:成功;匹配到的內(nèi)容是:"1";匹配到的位置是:開始于3,結(jié)束于4。


          1.5 修飾匹配次數(shù)的特殊符號

              前面章節(jié)中講到的表達(dá)式,無論是只能匹配一種字符的表達(dá)式,還是可以匹配多種字符其中任意一個的表達(dá)式,都只能匹配一次。如果使用表達(dá)式再加上修飾匹配次數(shù)的特殊符號,那么不用重復(fù)書寫表達(dá)式就可以重復(fù)匹配。

              使用方法是:"次數(shù)修飾"放在"被修飾的表達(dá)式"后邊。比如:"[bcd][bcd]" 可以寫成 "[bcd]{2}"。

          表達(dá)式

          作用

          {n}

          表達(dá)式重復(fù)n次,比如:

          {m,n}

          表達(dá)式至少重復(fù)m次,最多重復(fù)n次,比如:

          {m,}

          表達(dá)式至少重復(fù)m次,比如:

          ?

          匹配表達(dá)式0次或者1次,相當(dāng)于 {0,1},比如:

          +

          表達(dá)式至少出現(xiàn)1次,相當(dāng)于 {1,},比如:

          *

          表達(dá)式不出現(xiàn)或出現(xiàn)任意次,相當(dāng)于 {0,},比如:

              ,匹配的結(jié)果是:成功;匹配到的內(nèi)容是:"12.5";匹配到的位置是:開始于10,結(jié)束于14。

             
          ,匹配的結(jié)果是:成功;匹配到的內(nèi)容是:"goooooogle";匹配到的位置是:開始于7,結(jié)束于17。


          1.6 其他一些代表抽象意義的特殊符號

              一些符號在表達(dá)式中代表抽象的特殊意義:

          表達(dá)式

          作用

          ^

          與字符串開始的地方匹配,不匹配任何字符

          $

          與字符串結(jié)束的地方匹配,不匹配任何字符

          \b

          匹配一個單詞邊界,也就是單詞和空格之間的位置,不匹配任何字符

              進(jìn)一步的文字說明仍然比較抽象,因此,舉例幫助大家理解。

             
          ,匹配結(jié)果是:失敗。因為 "^" 要求與字符串開始的地方匹配,因此,只有當(dāng) "aaa" 位于字符串的開頭的時候,"^aaa" 才能匹配,

             
          ,匹配結(jié)果是:失敗。因為 "$" 要求與字符串結(jié)束的地方匹配,因此,只有當(dāng) "aaa" 位于字符串的結(jié)尾的時候,"aaa$" 才能匹配,

             
          ,匹配結(jié)果是:成功;匹配到的內(nèi)容是:"@a";匹配到的位置是:開始于2,結(jié)束于4。
              進(jìn)一步說明:"\b" 與 "^" 和 "$" 類似,本身不匹配任何字符,但是它要求它在匹配結(jié)果中所處位置的左右兩邊,其中一邊是 "\w" 范圍,另一邊是 非"\w" 的范圍。

             
          ,匹配結(jié)果是:成功;匹配到的內(nèi)容是:"end";匹配到的位置是:開始于15,結(jié)束于18。

              一些符號可以影響表達(dá)式內(nèi)部的子表達(dá)式之間的關(guān)系:

          表達(dá)式

          作用

          |

          左右兩邊表達(dá)式之間 "或" 關(guān)系,匹配左邊或者右邊

          ( )

          (1). 在被修飾匹配次數(shù)的時候,括號中的表達(dá)式可以作為整體被修飾
          (2). 取匹配結(jié)果的時候,括號中的表達(dá)式匹配到的內(nèi)容可以被單獨得到

              ,匹配結(jié)果是:成功;匹配到的內(nèi)容是:"Tom";匹配到的位置是:開始于4,結(jié)束于7。匹配下一個時,匹配結(jié)果是:成功;匹配到的內(nèi)容是:"Jack";匹配到的位置時:開始于15,結(jié)束于19。

             
          ,匹配結(jié)果是:成功;匹配到內(nèi)容是:"go go go";匹配到的位置是:開始于6,結(jié)束于14。

             
          ,匹配的結(jié)果是:成功;匹配到的內(nèi)容是:"¥20.5";匹配到的位置是:開始于6,結(jié)束于10。單獨獲取括號范圍匹配到的內(nèi)容是:"20.5"。


          2. 正則表達(dá)式中的一些高級規(guī)則

          2.1 匹配次數(shù)中的貪婪與非貪婪

              在使用修飾匹配次數(shù)的特殊符號時,有幾種表示方法可以使同一個表達(dá)式能夠匹配不同的次數(shù),比如:"{m,n}", "{m,}", "?", "*", "+",具體匹配的次數(shù)隨被匹配的字符串而定。這種重復(fù)匹配不定次數(shù)的表達(dá)式在匹配過程中,總是盡可能多的匹配。比如,針對文本 "dxxxdxxxd",舉例如下:

          表達(dá)式

          匹配結(jié)果

          (d)(\w+)

          "\w+" 將匹配第一個 "d" 之后的所有字符 "xxxdxxxd"

          (d)(\w+)(d)

          "\w+" 將匹配第一個 "d" 和最后一個 "d" 之間的所有字符 "xxxdxxx"。雖然 "\w+" 也能夠匹配上最后一個 "d",但是為了使整個表達(dá)式匹配成功,"\w+" 可以 "讓出" 它本來能夠匹配的最后一個 "d"

              由此可見,"\w+" 在匹配的時候,總是盡可能多的匹配符合它規(guī)則的字符。雖然第二個舉例中,它沒有匹配最后一個 "d",但那也是為了讓整個表達(dá)式能夠匹配成功。同理,帶 "*" 和 "{m,n}" 的表達(dá)式都是盡可能地多匹配,帶 "?" 的表達(dá)式在可匹配可不匹配的時候,也是盡可能的 "要匹配"。這 種匹配原則就叫作 "貪婪" 模式 。

              非貪婪模式:

              在修飾匹配次數(shù)的特殊符號后再加上一個 "?" 號,則可以使匹配次數(shù)不定的表達(dá)式盡可能少的匹配,使可匹配可不匹配的表達(dá)式,盡可能的 "不匹配"。這種匹配原則叫作 "非貪婪" 模式,也叫作 "勉強" 模式。如果少匹配就會導(dǎo)致整個表達(dá)式匹配失敗的時候,與貪婪模式類似,非貪婪模式會最小限度的再匹配一些,以使整個表達(dá)式匹配成功。舉例如下,針對文本 "dxxxdxxxd" 舉例:

          表達(dá)式

          匹配結(jié)果

          (d)(\w+?)

          "\w+?" 將盡可能少的匹配第一個 "d" 之后的字符,結(jié)果是:"\w+?" 只匹配了一個 "x"

          (d)(\w+?)(d)

          為了讓整個表達(dá)式匹配成功,"\w+?" 不得不匹配 "xxx" 才可以讓后邊的 "d" 匹配,從而使整個表達(dá)式匹配成功。因此,結(jié)果是:"\w+?" 匹配 "xxx"

              更多的情況,舉例如下:

             
          ,匹配的結(jié)果是:成功;匹配到的內(nèi)容是 "<td><p>aa</p></td> <td><p>bb</p></td>" 整個字符串, 表達(dá)式中的 "</td>" 將與字符串中最后一個 "</td>" 匹配。

             
          ,將只得到 "<td><p>aa</p></td>", 再次匹配下一個時,可以得到第二個 "<td><p>bb</p></td>"。


          2.2 反向引用 \1, \2...

              表達(dá)式在匹配時,表達(dá)式引擎會將小括號 "( )" 包含的表達(dá)式所匹配到的字符串記錄下來。在獲取匹配結(jié)果的時候,小括號包含的表達(dá)式所匹配到的字符串可以單獨獲取。這一點,在前面的舉例中,已經(jīng)多次展示了。在實際應(yīng)用場合中,當(dāng)用某種邊界來查找,而所要獲取的內(nèi)容又不包含邊界時,必須使用小括號來指定所要的范圍。比如前面的 "<td>(.*?)</td>"。

              其實,"小括號包含的表達(dá)式所匹配到的字符串" 不僅是在匹配結(jié)束后才可以使用,在匹配過程中也可以使用。表達(dá)式后邊的部分,可以引用前面 "括號內(nèi)的子匹配已經(jīng)匹配到的字符串"。引用方法是 "\" 加上一個數(shù)字。"\1" 引用第1對括號內(nèi)匹配到的字符串,"\2" 引用第2對括號內(nèi)匹配到的字符串……以此類推,如果一對括號內(nèi)包含另一對括號,則外層的括號先排序號。換句話說,哪一對的左括號 "(" 在前,那這一對就先排序號。

              舉例如下:

             
          ,匹配結(jié)果是:成功;匹配到的內(nèi)容是:" 'Hello' "。再次匹配下一個時,可以匹配到 " "World" "。

             
          ,匹配結(jié)果是:成功;匹配到的內(nèi)容是 "ccccc"。再次匹配下一個時,將得到 999999999。這個表達(dá)式要求 "\w" 范圍的字符至少重復(fù)5次,

             
          ,匹配結(jié)果是成功。如果 "<td>" 與 "</td>" 不配對,則會匹配失敗;如果改成其他配對,也可以匹配成功。


          2.3 預(yù)搜索,不匹配;反向預(yù)搜索,不匹配

              前面的章節(jié)中,我講到了幾個代表抽象意義的特殊符號:"^","$","\b"。它們都有一個共同點,那就是:它們本身不匹配任何字符,只是對 "字符串的兩頭" 或者 "字符之間的縫隙" 附加了一個條件。理解到這個概念以后,本節(jié)將繼續(xù)介紹另外一種對 "兩頭" 或者 "縫隙" 附加條件的,更加靈活的表示方法。

              正向預(yù)搜索:"(?=xxxxx)","(?!xxxxx)"

              格式:"(?=xxxxx)",在被匹配的字符串中,它對所處的 "縫隙" 或者 "兩頭" 附加的條件是:所在縫隙的右側(cè),必須能夠匹配上 xxxxx 這部分的表達(dá)式。因為它只是在此作為這個縫隙上附加的條件,所以它并不影響后邊的表達(dá)式去真正匹配這個縫隙之后的字符。這就類似 "\b",本身不匹配任何字符。"\b" 只是將所在縫隙之前、之后的字符取來進(jìn)行了一下判斷,不會影響后邊的表達(dá)式來真正的匹配。

             
          ,將只匹配 "Windows NT" 中的 "Windows ",其他的 "Windows " 字樣則不被匹配。

             
          ,將可以匹配6個"f"的前4個,可以匹配9個"9"的前7個。這個表達(dá)式可以讀解成:重復(fù)4次以上的字母數(shù)字,則匹配其剩下最后2位之前的部分。當(dāng)然,這個表達(dá)式可以不這樣寫,在此的目的是作為演示之用。

              格式:"(?!xxxxx)",所在縫隙的右側(cè),必須不能匹配 xxxxx 這部分表達(dá)式。

             
          ,將從頭一直匹配到 "stop" 之前的位置,如果字符串中沒有 "stop",則匹配整個字符串。

             
          ,只能匹配 "do"。在本條舉例中,"do" 后邊使用 "(?!\w)" 和使用 "\b" 效果是一樣的。

              反向預(yù)搜索:"(?<=xxxxx)","(?<!xxxxx)"

              這兩種格式的概念和正向預(yù)搜索是類似的,反向預(yù)搜索要求的條件是:所在縫隙的 "左側(cè)",兩種格式分別要求必須能夠匹配和必須不能夠匹配指定表達(dá)式,而不是去判斷右側(cè)。與 "正向預(yù)搜索" 一樣的是:它們都是對所在縫隙的一種附加條件,本身都不匹配任何字符。

              舉例5:表達(dá)式 "(?<=\d{4})\d+(?=\d{4})" 在匹配 "1234567890123456" 時,將匹配除了前4個數(shù)字和后4個數(shù)字之外的中間8個數(shù)字。由于 JScript.RegExp 不支持反向預(yù)搜索,因此,本條舉例不能夠進(jìn)行演示。很多其他的引擎可以支持反向預(yù)搜索,比如:Java 1.4 以上的 java.util.regex 包,.NET 中System.Text.RegularExpressions 命名空間,boost::regex 以及
          GRETA 正則表達(dá)式庫等。


          3. 其他通用規(guī)則

              還有一些在各個正則表達(dá)式引擎之間比較通用的規(guī)則,在前面的講解過程中沒有提到。

          3.1 表達(dá)式中,可以使用 "\xXX" 和 "\uXXXX" 表示一個字符("X" 表示一個十六進(jìn)制數(shù))

          形式

          字符范圍

          \xXX

          編號在 0 ~ 255 范圍的字符,比如:

          \uXXXX

          任何字符可以使用 "\u" 再加上其編號的4位十六進(jìn)制數(shù)表示,比如:

          3.2 在表達(dá)式 "\s","\d","\w","\b" 表示特殊意義的同時,對應(yīng)的大寫字母表示相反的意義

          表達(dá)式

          可匹配

          \S

          \D

          匹配所有的非數(shù)字字符

          \W

          匹配所有的字母、數(shù)字、下劃線以外的字符

          \B

          3.3 在表達(dá)式中有特殊意義,需要添加 "\" 才能匹配該字符本身的字符匯總

          字符

          說明

          ^

          匹配輸入字符串的開始位置。要匹配 "^" 字符本身,請使用 "\^"

          $

          匹配輸入字符串的結(jié)尾位置。要匹配 "$" 字符本身,請使用 "\$"

          ( )

          標(biāo)記一個子表達(dá)式的開始和結(jié)束位置。要匹配小括號,請使用 "\(" 和 "\)"

          [ ]

          用來自定義能夠匹配 '多種字符' 的表達(dá)式。要匹配中括號,請使用 "\[" 和 "\]"

          { }

          修飾匹配次數(shù)的符號。要匹配大括號,請使用 "\{" 和 "\}"

          .

          匹配除了換行符(\n)以外的任意一個字符。要匹配小數(shù)點本身,請使用 "\."

          ?

          修飾匹配次數(shù)為 0 次或 1 次。要匹配 "?" 字符本身,請使用 "\?"

          +

          修飾匹配次數(shù)為至少 1 次。要匹配 "+" 字符本身,請使用 "\+"

          *

          修飾匹配次數(shù)為 0 次或任意次。要匹配 "*" 字符本身,請使用 "\*"

          |

          左右兩邊表達(dá)式之間 "或" 關(guān)系。匹配 "|" 本身,請使用 "\|"

          3.4 括號 "( )" 內(nèi)的子表達(dá)式,如果希望匹配結(jié)果不進(jìn)行記錄供以后使用,可以使用 "(?:xxxxx)" 格式

              舉例1:表達(dá)式 "(?:(\w)\1)+" 匹配 "a bbccdd efg" 時,結(jié)果是 "bbccdd"。括號 "(?:)" 范圍的匹配結(jié)果不進(jìn)行記錄,因此 "(\w)" 使用 "\1" 來引用。

          3.5 常用的表達(dá)式屬性設(shè)置簡介:Ignorecase,Singleline,Multiline,Global

          表達(dá)式屬性

          說明

          Ignorecase

          默認(rèn)情況下,表達(dá)式中的字母是要區(qū)分大小寫的。配置為 Ignorecase 可使匹配時不區(qū)分大小寫。有的表達(dá)式引擎,把 "大小寫" 概念延伸至 UNICODE 范圍的大小寫。

          Singleline

          默認(rèn)情況下,小數(shù)點 "." 匹配除了換行符(\n)以外的字符。配置為 Singleline 可使小數(shù)點可匹配包括換行符在內(nèi)的所有字符。

          Multiline

          默認(rèn)情況下,表達(dá)式 "^" 和 "$" 只匹配字符串的開始 ① 和結(jié)尾 ④ 位置。如:

          ①xxxxxxxxx②\n
          ③xxxxxxxxx④

          配置為 Multiline 可以使 "^" 還可以匹配換行符之后,下一行開始前 ③ 的位置,使 "$" 還可以匹配換行符之前,一行結(jié)束 ② 的位置。

          Global

          主要在將表達(dá)式用來替換時起作用,配置為 Global 表示替換所有的匹配。


          4. 綜合提示

          4.1 如果要要求表達(dá)式所匹配的內(nèi)容是整個字符串,而不是從字符串中找一部分,那么可以在表達(dá)式的首尾使用 "^" 和 "$",比如:"^\d+$" 要求整個字符串只有數(shù)字。

          4.2 如果要求匹配的內(nèi)容是一個完整的單詞,而不會是單詞的一部分,那么在表達(dá)式首尾使用 "\b",比如:

          4.3 表達(dá)式不要匹配空字符串。否則會一直得到匹配成功,而結(jié)果什么都沒有匹配到。比如:準(zhǔn)備寫一個匹配 "123"、"123."、"123.5"、".5" 這幾種形式的表達(dá)式時,整數(shù)、小數(shù)點、小數(shù)數(shù)字都可以省略,但是不要將表達(dá)式寫成:"\d*\.?\d*",因為如果什么都沒有,這個表達(dá)式也可以匹配成功。

          4.4 能匹配空字符串的子匹配不要循環(huán)無限次。如果括號內(nèi)的子表達(dá)式中的每一部分都可以匹配 0 次,而這個括號整體又可以匹配無限次,那么情況可能比上一條所說的更嚴(yán)重,匹配過程中可能死循環(huán)。雖然現(xiàn)在有些正則表達(dá)式引擎已經(jīng)通過辦法避免了這種情況出現(xiàn)死循環(huán)了,比如 .NET 的正則表達(dá)式,但是我們?nèi)匀粦?yīng)該盡量避免出現(xiàn)這種情況。如果我們在寫表達(dá)式時遇到了死循環(huán),也可以從這一點入手,查找一下是否是本條所說的原因。

          4.5 合理選擇貪婪模式與非貪婪模式。

          4.6 或 "|" 的左右兩邊,對某個字符最好只有一邊可以匹配,這樣,不會因為 "|" 兩邊的表達(dá)式因為交換位置而有所不同。


          5. 搜索更多正則表達(dá)式支持

          在以下搜索字段中輸入關(guān)鍵字,查找問題的答案。

          posted @ 2006-02-22 10:47 Ben 閱讀(421) | 評論 (0)編輯 收藏

          了解DLL

          一、從DLL技術(shù)說起

          要了解DLL木馬,就必須知道這個“DLL”是什么意思,所以,讓我們追溯到幾年前,DOS系統(tǒng)大行其道的日子里。在那時候,寫程序是一件繁瑣的事情,因為每個程序的代碼都是獨立的,有時候為了實現(xiàn)一個功能,就要為此寫很多代碼,后來隨著編程技術(shù)發(fā)展,程序員們把很多常用的代碼集合(通用代碼)放進(jìn)一個獨立的文件里,并把這個文件稱為Library),在寫程序的時候,把這個庫文件加入編譯器,就能使用這個庫包含的所有功能而不必自己再去寫一大堆代碼,這個技術(shù)被稱為靜態(tài)鏈接Static Link)。靜態(tài)鏈接技術(shù)讓勞累的程序員松了口氣,一切似乎都很美好。可是事實證明,美好的事物不會存在太久,因為靜態(tài)鏈接就像一個粗魯?shù)耐其N員,不管你想不想要宣傳單,他都全部塞到你的手上來。寫一個程序只想用到一個庫文件包含的某個圖形效果,就因為這個,你不得不把這個庫文件攜帶的所有的圖形效果都加入程序,留著它們當(dāng)花瓶擺設(shè),這倒沒什么重要,可是這些花瓶卻把道路都阻塞了——靜態(tài)鏈接技術(shù)讓最終的程序成了大塊頭,因為編譯器把整個庫文件也算進(jìn)去了。

          時代在發(fā)展,靜態(tài)鏈接技術(shù)由于天生的弊端,不能滿足程序員的愿望,人們開始尋找一種更好的方法來解決代碼重復(fù)的難題。后來,Windows系統(tǒng)出現(xiàn)了,時代的分水嶺終于出現(xiàn)。Windows系統(tǒng)使用一種新的鏈接技術(shù),這種被稱為動態(tài)鏈接Dynamic Link)的新技術(shù)同樣也是使用庫文件,微軟稱它們?yōu)?/SPAN>動態(tài)鏈接庫”——Dynamic Link LibraryDLL的名字就是這樣來的。動態(tài)鏈接本身和靜態(tài)鏈接沒什么區(qū)別,也是把通用代碼寫進(jìn)一些獨立文件里,但是在編譯方面,微軟繞了個圈子,并沒有采取把庫文件加進(jìn)程序的方法,而是把庫文件做成已經(jīng)編譯好的程序文件,給它們開個交換數(shù)據(jù)的接口,程序員寫程序的時候,一旦要使用某個庫文件的一個功能函數(shù),系統(tǒng)就把這個庫文件調(diào)入內(nèi)存,連接上這個程序占有的任務(wù)進(jìn)程,然后執(zhí)行程序要用的功能函數(shù),并把結(jié)果返回給程序顯示出來,在我們看來,就像是程序自己帶有的功能一樣。完成需要的功能后,這個DLL停止運行,整個調(diào)用過程結(jié)束。微軟讓這些庫文件能被多個程序調(diào)用,實現(xiàn)了比較完美的共享,程序員無論要寫什么程序,只要在代碼里加入對相關(guān)DLL的調(diào)用聲明就能使用它的全部功能。最重要的是,DLL絕對不會讓你多拿一個花瓶,你要什么它就給你什么,你不要的東西它才不會給你。這樣,寫出來的程序就不能再攜帶一大堆垃圾了——絕對不會讓你把吃剩的東西帶回家,否則罰款,這是自助餐。

          DLL
          技術(shù)的誕生,使編寫程序變成一件簡單的事情,Windows為我們提供了幾千個函數(shù)接口,足以滿足大多數(shù)程序員的需要。而且,Windows系統(tǒng)自身就是由幾千個DLL文件組成,這些DLL相互扶持,組成了強大的Windows系統(tǒng)。如果Windows使用靜態(tài)鏈接技術(shù),它的體積會有多大?我不敢想。

          二、應(yīng)用程序接口API

          上面我們對DLL技術(shù)做了個大概分析,在里面我提到了接口,這又是什么呢?因為DLL不能像靜態(tài)庫文件那樣塞進(jìn)程序里,所以,如何讓程序知道實現(xiàn)功能的代碼和文件成了問題,微軟就為DLL技術(shù)做了標(biāo)準(zhǔn)規(guī)范,讓一個DLL文件像奶酪一樣開了許多小洞,每個洞口都注明里面存放的功能的名字,程序只要根據(jù)標(biāo)準(zhǔn)規(guī)范找到相關(guān)洞口就可以取得它要的美味了,這個洞口就是應(yīng)用程序接口Application Programming Interface),每個DLL帶的接口都不相同,盡最大可能的減少了代碼的重復(fù)。用Steven的一句話:API就是一個工具箱,你根據(jù)需要取出螺絲刀、扳手,用完后再把它們放回原處。在Windows里,最基本的3DLL文件是kernel32.dlluser32.dllgdi32.dll。它們共同構(gòu)成了基本的系統(tǒng)框架。

          posted @ 2006-02-17 11:25 Ben 閱讀(264) | 評論 (0)編輯 收藏

          主站蜘蛛池模板: 东辽县| 乌苏市| 平江县| 岳阳县| 滨海县| 上虞市| 丹江口市| 措美县| 安顺市| 新晃| 白水县| 吉隆县| 若尔盖县| 安塞县| 英超| 工布江达县| 恩施市| 太康县| 监利县| 泗洪县| 凤翔县| 武冈市| 利川市| 丰城市| 翼城县| 垫江县| 许昌县| 安康市| 辽宁省| 文昌市| 吴桥县| 绍兴市| 梁平县| 姚安县| 密山市| 涪陵区| 亚东县| 贵定县| 库车县| 宽城| 山阳县|