整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          sqlserver存儲過程sp_send_dbmail郵件(html)實(shí)際應(yīng)用

          段時(shí)間因工作需求,特地學(xué)習(xí)了下sp_send_dbmail的使用,好不容易完工來和大家分享一下,不談理論,只管實(shí)踐!

          如下是實(shí)際需求:

          -- =============================================
          -- Title: 集團(tuán)資質(zhì)一覽表
          -- Description1:<1、距離到期日期1年內(nèi)和已過期的發(fā)到期提醒>
          -- Description2:<2、表頭【非附件】:公司名稱、發(fā)證部門、證書名稱、類別、等級、到期日期、預(yù)警級別>
          -- Description3:<3、預(yù)警級別:假設(shè)距離到期日期月數(shù)為N。一級:N<=3;二級:3<N<=6;三級:N>=6>
          -- Description4:<4、提醒人員:郵件提醒
          -- =============================================

          在這里sp_send_dbmail的參數(shù)不去做詳述(我也不懂~),實(shí)際過程中我們需要用到的并不多,只需下面幾行就能發(fā)送html格式的郵件了

          Exec dbo.sp_send_dbmail 
          @profile_name='crm***', --發(fā)件人姓名 
          @recipients='156240***@qq.com', --郵箱(多個(gè)用;隔開)
          @body=@tableHTML, --消息主體 
          @body_format='HTML', --指定消息的格式,一般文本直接去掉即可,發(fā)送html格式的內(nèi)容需加上
          @subject ='資質(zhì)到期預(yù)警'; -- 消息的主題

          下面最主要的部分就是@tableHTML了,在這里我們使用兩種方式去拼接html。

          1.通過sql CAST 函數(shù),網(wǎng)上的示例大多數(shù)是這種,愚笨的我不太看得懂,只能依瓢。

          declare @tableHTML varchar(max)
          SET @tableHTML =
          N'<H1 style="text-align:center">資質(zhì)相關(guān)信息</H1>' +
          N'<table border="1" cellpadding="3" cellspacing="0" align="center">' +
          N'<tr><th width=100px" >公司名稱</th>'+
          N'<th width=250px>發(fā)證部門</th><th width=150px>證書名稱</th>'+
          N'<th width=50px>類別</th><th width=50px>等級</th>'+
          N'<th width=60px>到期日期</th><th width=60px>預(yù)警級別</th></tr>'+
          CAST ( (
          select td = p.CompanyName, '',td = p.DeptName, '',td=p.Name,'', td = p.QualificationType, '',td = p.Level, '',td = p.ExpireDates, '',td=p.YJ,''
          from(    
              select   
              CompanyName,DeptName,Name,QualificationType,Level,Convert(varchar(50),ExpireDate,111)ExpireDates,
              case when DATEDIFF(mm,getDate(),ExpireDate)<=3 then '一級預(yù)警' 
              when DATEDIFF(mm,getDate(),ExpireDate)<=6 then '二級預(yù)警' else '三級預(yù)警'end YJ
              from  T_Market***_JTZZ 
              where 12>=DATEDIFF(mm,getDate(),ExpireDate)
          ) p order by  p.ExpireDates  asc
          FOR XML PATH('tr'), TYPE
          ) AS NVARCHAR(MAX) ) +
          N'</table>' ;
          
          Exec dbo.sp_send_dbmail 
              @profile_name='crm***', 
              @recipients = '156240***@qq.com', 
              @subject='資質(zhì)到期預(yù)警', 
              @body=@tableHTML,
              @body_format = 'HTML' ;

          2.通過游標(biāo)動(dòng)態(tài)繪制html,感覺這種更方便,雖然寫起來有點(diǎn)啰嗦,但很靈活。

          BEGIN
              declare @tableHTML varchar(max)
              declare @Companyname varchar(250) --公司名稱
              declare @Deptname varchar(250)    --發(fā)證部門
              declare @Certname varchar(250)    --證書名稱
              declare @Certtype varchar(50)     --證書類別
              declare @Certlevel varchar(50)    --證書等級
              declare @Expirdate varchar(20)    --到期時(shí)間
              declare @Warnlevel varchar(20)    --預(yù)警級別
              
              begin
                  set @tableHTML = '<html><body><table><tr><td><p><font color="#000080" size="3" face="Verdana">您好!</font></p><p style="margin-left:30px;"><font size="3" face="Verdana">以下資質(zhì)即將到期或已過期,請盡快辦理資質(zhì)延續(xù):</font></p></td></tr>';
                  --創(chuàng)建臨時(shí)表#tbl_result
                  create table #tbl_result(companyname varchar(250),deptname varchar(250),certname varchar(250),certtype varchar(50),certlevel varchar(50),expirdate varchar(20),warnlevel varchar(10));
                  insert into #tbl_result 
                  select CompanyName,DeptName,Name,QualificationType,Level,convert(varchar(20),ExpireDate,23) ExpireDate,case when ms<=3 then '一級' when ms>3 and ms<=6 then '二級' else '三級' end warnlevel
                  from (
                      select *,Datediff(MONTH,GETDATE(),ExpireDate) ms
                      from T_Market***_JTZZ 
                      where ExpireDate is not null and Datediff(MONTH,GETDATE(),ExpireDate)<=12
                  ) res;
                  
                  declare @counts int;
                  select @counts=count(*) from #tbl_result;
                  --- 提醒列表
                  if(@counts>0)
                  begin
                      set @tableHTML=@tableHTML+'<tr><td><table border="1" style="border:1px solid #d5d5d5;border-collapse:collapse;border-spacing:0;margin-left:30px;margin-top:20px;"><tr style="height:25px;background-color: rgb(219, 240, 251);"><th style="width:100px;">公司名稱</th><th style="width:200px;">發(fā)證部門</th><th>證書名稱</th><th style="width:60px;">類別</th><th style="width:80px;">等級</th><th style="width:100px;">到期日期</th><th style="width:80px;">預(yù)警級別</th></tr>';
                      --申明游標(biāo)
                      Declare cur_cert Cursor for
                      select companyname,deptname,certname,certtype,certlevel,expirdate,warnlevel from #tbl_result order by expirdate;
                      --打開游標(biāo)
                      open cur_cert
                      --循環(huán)并提取記錄
                      Fetch Next From cur_cert Into @Companyname,@Deptname,@Certname,@Certtype,@Certlevel,@Expirdate,@Warnlevel
                      While (@@Fetch_Status=0)
                      begin
                          set @tableHTML = @tableHTML + '<tr><td align="center">'+@Companyname+'</td>';
                          set @tableHTML = @tableHTML + '<td align="center">'+@Deptname+'</td>';
                          set @tableHTML = @tableHTML + '<td align="center">'+@Certname+'</td>';
                          set @tableHTML = @tableHTML + '<td align="center">'+@Certtype+'</td>';
                          set @tableHTML = @tableHTML + '<td align="center">'+@Certlevel+'</td>';
                          set @tableHTML = @tableHTML + '<td align="center">'+@Expirdate+'</td>';
                          set @tableHTML = @tableHTML + '<td align="center">'+@Warnlevel+'</td></tr>';
                          --繼續(xù)遍歷下一條記錄
                          Fetch Next From cur_cert Into @Companyname,@Deptname,@Certname,@Certtype,@Certlevel,@Expirdate,@Warnlevel
                      end
                      --關(guān)閉游標(biāo)
                      Close cur_cert
                      --釋放游標(biāo)
                      Deallocate cur_cert
                      set @tableHTML = @tableHTML + '</table></td></tr>';
                  end
                  
                  -- 發(fā)送郵件
                      exec msdb.dbo.sp_send_dbmail 
                      @profile_name='crm***',
                      @recipients='156240***@qq.com',
                      @body=@tableHTML,
                      @body_format='HTML',
                      @subject ='資質(zhì)到期預(yù)警';
                      
                  -- 刪除臨時(shí)表(#tbl_result)
                  if object_id('tempdb..#tbl_result') is not null 
                  begin
                      drop table #tbl_result;
                  end
              end
          
          END

          看起來無疑第二種特別啰嗦,但個(gè)人感覺很好理解,游標(biāo)拼接html部分思路很清楚,以上兩個(gè)方式均經(jīng)過實(shí)踐,如需使用只需要將其中對應(yīng)的字段、數(shù)據(jù)源替換掉即可,感謝諸位賞足,有什么不足之處還望大家見諒,

          做項(xiàng)目的過程中,我們經(jīng)常遇到需要把信息存儲在本地的情況,比如權(quán)限驗(yàn)證的token、用戶信息、埋點(diǎn)計(jì)數(shù)、客戶配置的皮膚信息或語言種類等,我們可以暫存一下避免瀏覽器不必要的請求和客戶多余操作,給客戶使用帶來方便。

          上一篇講了JavaScript瀏覽器端數(shù)據(jù)存儲方案之Cookie篇,這篇文章主要介紹localStorage和sessionStorage。

          HTML5中 Web Storage 的出現(xiàn),主要是為了彌補(bǔ)使用 Cookie 作為本地存儲的不足。Cookie 存儲的數(shù)據(jù)量非常小,而且數(shù)據(jù)會(huì)自動(dòng)攜帶到請求頭里,但服務(wù)器端可能并不關(guān)心這些數(shù)據(jù),所以會(huì)造成帶寬的浪費(fèi)。

          Web Storage 提供了兩個(gè)存儲對象:localStorage 和 sessionStorage

          sessionStorage 存儲的數(shù)據(jù)僅在本次會(huì)話有用,會(huì)話結(jié)束后會(huì)自動(dòng)失效,而且數(shù)據(jù)僅在當(dāng)前窗口有效,同一源下新窗口也訪問不到其他窗口基于sessionStorage 存儲的數(shù)據(jù)。也是由于這些特性,導(dǎo)致 sessionStorage 的使用場景會(huì)比較少。

          localStorage 可以永久存儲,而且同源下數(shù)據(jù)多窗口也能共享。看起來很美好,但 localStorage 也有短板,絕大多數(shù)瀏覽器有 5M 的大小限制。但是這不足以成為大家使用 localStorage 的障礙,要知道 Cookie 只有 4K 的大小,多了一千多倍

          localStorage 的基本使用

          localStorage.setItem("b","isaac");//設(shè)置b為"isaac"
          var b = localStorage.getItem("b");//獲取b的值,為"isaac"
          var a = localStorage.key(0); // 獲取第0個(gè)數(shù)據(jù)項(xiàng)的鍵名,此處即為“b”
          localStorage.removeItem("b");//清除c的值
          localStorage.clear();//清除當(dāng)前域名下的所有l(wèi)ocalstorage數(shù)據(jù)
          

          這里和大家分享一段我們在VUE項(xiàng)目中封裝使用的localStorage,大家可以借鑒實(shí)現(xiàn)的思路

          有兩點(diǎn)需要注意一下。在 setItem 時(shí),可能會(huì)達(dá)到大小限制,最好加上錯(cuò)誤捕捉

          另外在存儲容量快滿時(shí),會(huì)造成 getItem 性能急劇下降。我們下面看看 localStorage 有哪些腦洞大開的用法

          緩存靜態(tài)文件

          你不禁要問,HTTP 協(xié)議不是本來就支持緩存文件嗎,為什么還要使用 localStorage 來緩存?為了可編程化,通俗一點(diǎn)說就是把命運(yùn)握在自己手中。

          HTTP 協(xié)議的緩存,可以由用戶瀏覽器清除或禁用緩存,也可以由 Web 服務(wù)器設(shè)置過期時(shí)間或不緩存。對于前端工程師,這更像是一個(gè)黑盒,想要決定文件是訪問緩存還是訪問遠(yuǎn)程顯得有些力不從心了。

          使用 localStorage 控制文件緩存的方式有兩種:

          1. 使用 Loader 加載靜態(tài)文件
          2. 借助服務(wù)器端將靜態(tài)文件 inline 化

          這兩種方式一般都會(huì)提前做好緩存過期策略,通常是使用版本號來控制,下面還會(huì)細(xì)講。否則文件新版上線,用戶客戶端還是舊版,這就麻煩大了,而且這類問題,還不好調(diào)試不好重現(xiàn)。

          使用 Loader 加載靜態(tài)文件

          由于請求都是動(dòng)態(tài)發(fā)出的,所以可以對請求攔截處理。大致流程如下:

          1. 查看請求的文件 url 是否有緩存到 localStorage
          2. 如果沒有,到第 2 大步
          3. 如果有,判斷文件是否過期或版本號是否匹配
          4. 過期或不匹配,到第 2 大步
          5. 文件內(nèi)容有效,到第 4 大步
          6. 請求遠(yuǎn)程文件
          7. 緩存最新文件內(nèi)容
          8. 執(zhí)行文件內(nèi)容

          這個(gè)方式有個(gè)開源庫:basket.js(可以在github上訪問)

          借助服務(wù)器端將靜態(tài)文件 inline 化

          這個(gè)方式比上面那種更進(jìn)一步,在第一次響應(yīng)時(shí)把需要放入 localStorage 的文件都內(nèi)聯(lián)進(jìn) html 中,后面每次響應(yīng)只要文件版本沒有變化,都是渲染一段從 localStorage 加載該文件的代碼。這樣做的好處是可以有效減少請求次數(shù),即使是第一次。

          版本號不匹配(版本號可記在 Cookie 中,第一次訪問沒有版本號),服務(wù)端響應(yīng)內(nèi)容:

          <script> 
          function script2ls(id) { 
           var script = document.getElementById(id);
           if (script) {
           localStorage[id] = script.innerHTML;
           }
          }
          </script>
          <script id="jquery.js">...jquery source code...</script> 
          <script>script2ls('jquery.js')</script> 
          

          版本號匹配,服務(wù)端響應(yīng)內(nèi)容:

          <script> 
          function ls2script(id) { 
           var script = document.createElement('script');
           script.text = localStorage[id];
           document.head.appendChild(script);
          }
          </script>
          <script>ls2script('jquery.js')</script> 
          

          不過使用 localStorage 緩存文件會(huì)有 XSS 的風(fēng)險(xiǎn),而且造成的傷害可能是永久的

          同源窗口通信

          你可能不禁又要問,不是有 postMessage 嗎?沒錯(cuò) postMessage 確實(shí)可以用于窗口或 iframe 間通信,但是前提是你必須拿到打開新窗或 iframe 的句柄對象:

          var popup = window.open(...popup details...); 
          popup.postMessage("hello there!", "http://example.com"); 
          

          這樣在新窗中再打開新窗,似乎就不好傳遞消息了。

          你可能還想問,為什么要在窗口間通信?好問題,沒有應(yīng)用場景的技術(shù)都是耍流氓。像多窗口共用的一些組件,而且對數(shù)據(jù)實(shí)時(shí)同步都有較高要求的都會(huì)是這個(gè)技術(shù)的應(yīng)用場景。比如通知中心上面的未讀數(shù)量,兩個(gè)窗口,A 窗口更新為 8,切到 B 窗口還是 9,這就造成了體驗(yàn)不一致,這個(gè)例子可能還覺得無關(guān)痛癢;再比如購物車,兩個(gè)產(chǎn)品窗口,A 窗口添加到購物車,切到 B 窗口添加到購物車,發(fā)現(xiàn)沒有 A 添加的產(chǎn)品,這樣就比較嚴(yán)重了。這當(dāng)然也可以通過每個(gè)窗口都與后臺建立連接來更新,但用戶如果開十幾個(gè)窗口就開銷大了。

          有了同源窗口通信,我們就可以只有一個(gè)窗口與后臺建立連接,收到更新后,廣播給其他窗口就可以。說了這么多,實(shí)現(xiàn)原理是怎樣的呢?

          其實(shí)原理也簡單,每次 localStorage 中有任何變動(dòng)都會(huì)觸發(fā)一個(gè) storage 事件,所有窗口都監(jiān)聽這個(gè)事件,一旦有窗口更新 localStorage,其他窗口都會(huì)收到通知,根據(jù)事件中的 key 把不關(guān)心的變動(dòng)過濾掉。原理是很簡單,但是要實(shí)現(xiàn)一套完整的廣播機(jī)制還是有些復(fù)雜,你需要:

          • 管理好每個(gè)窗口的唯一 ID
          • 防止消息重復(fù)
          • 防止消息發(fā)給不關(guān)心的窗口
          • 窗口心跳 keep alive
          • 主窗口選舉
          • ...

          不用擔(dān)心,已經(jīng)有了不錯(cuò)的開源實(shí)現(xiàn):diy/intercom.js、tejacques/crosstab

          作為前端 DB 的存儲介質(zhì)

          你可能不滿足于用鍵值對保存數(shù)據(jù),你還想保存更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。

          靈活存取 json 格式的數(shù)據(jù):typicode/lowdb

          通過 sql 對數(shù)據(jù) CURD 操作:agershun/alasql

          表單自動(dòng)持久化

          在填寫表單時(shí),遇到瀏覽器奔潰或者誤操作導(dǎo)致填寫內(nèi)容丟失,此刻用戶的內(nèi)心也應(yīng)該是奔潰的。誤操作還可以加一個(gè) beforeunload 事件,在關(guān)閉瀏覽器或跳出當(dāng)前頁前提醒一下用戶。那瀏覽器崩潰呢,將數(shù)據(jù)變更實(shí)時(shí)保存到后臺,這樣似乎開銷很大,實(shí)時(shí)保存到 localStorage 是個(gè)不錯(cuò)的解決方案,真巧,也有一個(gè)開源實(shí)現(xiàn):simsalabim/sisyphus

          TML5是最新的HTML標(biāo)準(zhǔn),是專門為承載豐富的web內(nèi)容而設(shè)計(jì)的,并且無需額外插件。接下來小編就為大家講解HTML5的5種存儲方式:

          1.本地存儲localstorage

          存儲方式:

          以鍵值對(Key-Value)的方式存儲,永久存儲,永不失效,除非手動(dòng)刪除。

          大小:

          每個(gè)域名5M

          支持情況:

          注意:IE9 localStorage不支持本地文件,需要將項(xiàng)目署到服務(wù)器,才可以支持!

          if(window.localStorage){ alert('This browser supports localStorage'); }else{ alert('This browser does NOT support localStorage'); }

          常用的API:

          getItem //取記錄

          setIten//設(shè)置記錄

          removeItem//移除記錄

          key//取key所對應(yīng)的值

          clear//清除記錄

          存儲的內(nèi)容:

          數(shù)組,圖片,json,樣式,腳本。。。(只要是能序列化成字符串的內(nèi)容都可以存儲)

          2.本地存儲sessionstorage

          HTML5 的本地存儲 API 中的 localStorage 與 sessionStorage 在使用方法上是相同的,區(qū)別在于 sessionStorage 在關(guān)閉頁面后即被清空,而 localStorage 則會(huì)一直保存。

          3.離線緩存(application cache)

          本地緩存應(yīng)用所需的文件

          使用方法:

          ①配置manifest文件

          頁面上:

          ...

          Manifest 文件:

          manifest 文件是簡單的文本文件,它告知瀏覽器被緩存的內(nèi)容(以及不緩存的內(nèi)容)。

          manifest 文件可分為三個(gè)部分:

          ①CACHE MANIFEST - 在此標(biāo)題下列出的文件將在首次下載后進(jìn)行緩存

          ②NETWORK - 在此標(biāo)題下列出的文件需要與服務(wù)器的連接,且不會(huì)被緩存

          ③FALLBACK - 在此標(biāo)題下列出的文件規(guī)定當(dāng)頁面無法訪問時(shí)的回退頁面(比如 404 頁面)

          完整demo:

          CACHE MANIFEST # 2016-07-24 v1.0.0 /theme.css /main.js NETWORK: login.jsp FALLBACK: /html/ /offline.html

          服務(wù)器上:manifest文件需要配置正確的MIME-type,即 "text/cache-manifest"。

          如Tomcat:

          manifest text/cache-manifest

          常用API:

          核心是applicationCache對象,有個(gè)status屬性,表示應(yīng)用緩存的當(dāng)前狀態(tài):

          0(UNCACHED) : 無緩存, 即沒有與頁面相關(guān)的應(yīng)用緩存

          1(IDLE) : 閑置,即應(yīng)用緩存未得到更新

          2 (CHECKING) : 檢查中,即正在下載描述文件并檢查更新

          3 (DOWNLOADING) : 下載中,即應(yīng)用緩存正在下載描述文件中指定的資源

          4 (UPDATEREADY) : 更新完成,所有資源都已下載完畢

          5 (IDLE) : 廢棄,即應(yīng)用緩存的描述文件已經(jīng)不存在了,因此頁面無法再訪問應(yīng)用緩存

          相關(guān)的事件:

          表示應(yīng)用緩存狀態(tài)的改變:

          checking : 在瀏覽器為應(yīng)用緩存查找更新時(shí)觸發(fā)

          error : 在檢查更新或下載資源期間發(fā)送錯(cuò)誤時(shí)觸發(fā)

          noupdate : 在檢查描述文件發(fā)現(xiàn)文件無變化時(shí)觸發(fā)

          downloading : 在開始下載應(yīng)用緩存資源時(shí)觸發(fā)

          progress:在文件下載應(yīng)用緩存的過程中持續(xù)不斷地下載地觸發(fā)

          updateready : 在頁面新的應(yīng)用緩存下載完畢觸發(fā)

          cached : 在應(yīng)用緩存完整可用時(shí)觸發(fā)

          Application Cache的三個(gè)優(yōu)勢:

          ① 離線瀏覽

          ② 提升頁面載入速度

          ③ 降低服務(wù)器壓力

          注意事項(xiàng):

          1. 瀏覽器對緩存數(shù)據(jù)的容量限制可能不太一樣(某些瀏覽器設(shè)置的限制是每個(gè)站點(diǎn) 5MB)

          2. 如果manifest文件,或者內(nèi)部列舉的某一個(gè)文件不能正常下載,整個(gè)更新過程將視為失敗,瀏覽器繼續(xù)全部使用老的緩存

          3. 引用manifest的html必須與manifest文件同源,在同一個(gè)域下

          4. 瀏覽器會(huì)自動(dòng)緩存引用manifest文件的HTML文件,這就導(dǎo)致如果改了HTML內(nèi)容,也需要更新版本才能做到更新。

          5. manifest文件中CACHE則與NETWORK,F(xiàn)ALLBACK的位置順序沒有關(guān)系,如果是隱式聲明需要在最前面

          6. FALLBACK中的資源必須和manifest文件同源

          7. 更新完版本后,必須刷新一次才會(huì)啟動(dòng)新版本(會(huì)出現(xiàn)重刷一次頁面的情況),需要添加監(jiān)聽版本事件。

          8. 站點(diǎn)中的其他頁面即使沒有設(shè)置manifest屬性,請求的資源如果在緩存中也從緩存中訪問

          9. 當(dāng)manifest文件發(fā)生改變時(shí),資源請求本身也會(huì)觸發(fā)更新

          離線緩存與傳統(tǒng)瀏覽器緩存區(qū)別:

          1. 離線緩存是針對整個(gè)應(yīng)用,瀏覽器緩存是單個(gè)文件

          2. 離線緩存斷網(wǎng)了還是可以打開頁面,瀏覽器緩存不行

          3. 離線緩存可以主動(dòng)通知瀏覽器更新資源

          4.Web SQL

          關(guān)系數(shù)據(jù)庫,通過SQL語句訪問

          Web SQL 數(shù)據(jù)庫 API 并不是 HTML5 規(guī)范的一部分,但是它是一個(gè)獨(dú)立的規(guī)范,引入了一組使用 SQL 操作客戶端數(shù)據(jù)庫的 APIs。

          支持情況:

          Web SQL 數(shù)據(jù)庫可以在最新版的 Safari, Chrome 和 Opera 瀏覽器中工作。

          核心方法:

          ①openDatabase:這個(gè)方法使用現(xiàn)有的數(shù)據(jù)庫或者新建的數(shù)據(jù)庫創(chuàng)建一個(gè)數(shù)據(jù)庫對象。

          ②transaction:這個(gè)方法讓我們能夠控制一個(gè)事務(wù),以及基于這種情況執(zhí)行提交或者回滾。

          ③executeSql:這個(gè)方法用于執(zhí)行實(shí)際的 SQL 查詢。

          打開數(shù)據(jù)庫:

          var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024,fn); //openDatabase() 方法對應(yīng)的五個(gè)參數(shù)分別為:數(shù)據(jù)庫名稱、版本號、描述文本、數(shù)據(jù)庫大小、創(chuàng)建回調(diào)

          執(zhí)行查詢操作:

          var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024); db.transaction(function (tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS WIN (id unique, name)'); });

          插入數(shù)據(jù): 

          var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024); db.transaction(function (tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS WIN (id unique, name)'); tx.executeSql('INSERT INTO WIN (id, name) VALUES (1, "winty")'); tx.executeSql('INSERT INTO WIN (id, name) VALUES (2, "LuckyWinty")'); });

          讀取數(shù)據(jù):

          db.transaction(function (tx) { tx.executeSql('SELECT * FROM WIN', [], function (tx, results) { var len = results.rows.length, i; msg = "

          查詢記錄條數(shù): " + len + "

          "; document.querySelector('#status').innerHTML += msg; for (i = 0; i <>

          alert(results.rows.item(i).name ); } }, null); });

          由這些操作可以看出,基本上都是用SQL語句進(jìn)行數(shù)據(jù)庫的相關(guān)操作,如果你會(huì)MySQL的話,這個(gè)應(yīng)該比較容易用。

          5.IndexedDB

          索引數(shù)據(jù)庫 (IndexedDB) API(作為 HTML5 的一部分)對創(chuàng)建具有豐富本地存儲數(shù)據(jù)的數(shù)據(jù)密集型的離線 HTML5 Web 應(yīng)用程序很有用。同時(shí)它還有助于本地緩存數(shù)據(jù),使傳統(tǒng)在線 Web 應(yīng)用程序(比如移動(dòng) Web 應(yīng)用程序)能夠更快地運(yùn)行和響應(yīng)。


          主站蜘蛛池模板: 97久久精品午夜一区二区| 国产成人一区二区三区高清| 麻豆AV无码精品一区二区| 国产肥熟女视频一区二区三区| 精品视频一区二区三区| 亚洲av色香蕉一区二区三区蜜桃| 亚洲一区二区三区在线观看精品中文 | 国产萌白酱在线一区二区| 亚洲AV成人一区二区三区AV| 久久精品国产一区二区 | 国产vr一区二区在线观看| 国产精品综合一区二区| 亚洲日韩AV一区二区三区中文| 无码AV中文一区二区三区| 日本一区二区在线| 日本免费一区二区久久人人澡| 精品一区二区三区免费观看| 免费人人潮人人爽一区二区| 日韩高清一区二区三区不卡| 国模吧一区二区三区精品视频| 国产精品一区视频| 国产精品久久久久一区二区三区 | 无码人妻AV免费一区二区三区| 寂寞一区在线观看| 精品亚洲A∨无码一区二区三区| 国产在线无码一区二区三区视频| 国产精品视频一区二区三区四| 无码一区二区三区免费| 亚洲狠狠狠一区二区三区| 激情内射亚洲一区二区三区爱妻 | 国产亚洲自拍一区| 亚洲一区二区三区夜色| 国产精品亚洲午夜一区二区三区 | 无码一区二区三区视频| 亚洲视频免费一区| 日韩精品福利视频一区二区三区| 国产伦理一区二区三区| 国产av福利一区二区三巨| 性无码一区二区三区在线观看| 在线欧美精品一区二区三区| 国产免费av一区二区三区|