狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

[點晴永久免費OA]ASP程序與SQL存儲過程結合使用詳解

admin
2022年6月21日 19:4 本文熱度 1099

    定義總是很抽象,存儲進程其實就是能完成特定操作的一組SQL語句,只不過這組語句是放在數據庫中的(這里我們只談SQL SERVER)。如果我們通過創建存儲進程以及在ASP中調用存儲進程,就可以避免將SQL語句同ASP代碼混雜在一起。這樣做的好處至少有三個:
  第一、大大提高效率。存儲進程本身的執行速度非常快,而且,調用存儲進程可以大大減少同數據庫的交互次數。
  第二、提高安全性。假如將SQL語句混合在ASP代碼中,一旦代碼失密,同時也就意味著庫結構失密。
  第三、有利于SQL語句的重用。


  在ASP中,一般通過COMMAND對象調用存儲進程,根據不同情況,本文也介紹其它調用方法。為了方便說明,根據存儲進程的輸入輸出,作以下簡單分類:
  1. 只返回單一記錄集的存儲進程
  假設有以下存儲進程(本文的目的不在于講述T-SQL語法,所以存儲進程只給出代碼,不作說明):

  /*SP1*/
  create PROCEDURE DBO.GETUSERLIST
  AS
  SET NOCOUNT ON
  BEGIN
  select * from DBO.[USERINFO]
  END
  GO

  以上存儲進程取得USERINFO表中的所有記錄,返回一個記錄集。通過COMMAND對象調用該存儲進程的ASP代碼如下:
  '**通過COMMAND對象調用存儲進程**
  DIM MYCOMM,MYRST
  SET MYCOMM = SERVER.createOBJECT("ADODB.COMMAND")
  MYCOMM.ACTIVECONNECTION = MYCONSTR    'MYCONSTR是數據庫連接字串
  MYCOMM.COMMANDTEXT  = "GETUSERLIST"   '指定存儲進程名
  MYCOMM.COMMANDTYPE  = 4      '表明這是一個存儲進程
  MYCOMM.PREPARED    = TRUE      '要求將SQL命令先行編譯
  SET MYRST = MYCOMM.execUTE
  SET MYCOMM = NOTHING

  存儲進程取得的記錄集賦給MYRST,接下來,可以對MYRST進行操作。
  在以上代碼中,COMMANDTYPE屬性表明請求的類型,取值及說明如下:
  -1   表明COMMANDTEXT參數的類型無法確定
  1  表明COMMANDTEXT是一般的命令類型
  2  表明COMMANDTEXT參數是一個具有的表名稱
  4  表明COMMANDTEXT參數是一個存儲進程的名稱

  還可以通過CONNECTION對象或RECORDSET對象調用存儲進程,方法分別如下:

  '**通過CONNECTION對象調用存儲進程**
  DIM MYCONN,MYRST
  SET MYCONN = SERVER.createOBJECT("ADODB.CONNECTION")
  MYCONN.OPEN MYCONSTR          'MYCONSTR是數據庫連接字串
  SET MYRST  = MYCONN.execUTE("GETUSERLIST",0,4) '最后一個參斷含義同COMMANDTYPE
  SET MYCONN = NOTHING

  '**通過RECORDSET對象調用存儲進程**
  DIM MYRST
  SET MYRST = SERVER.createOBJECT("ADODB.RECORDSET")
  MYRST.OPEN "GETUSERLIST",MYCONSTR,0,1,4
  'MYCONSTR是數據庫連接字串,最后一個參斷含義與COMMANDTYPE相同

  
  2. 沒有輸入輸出的存儲進程
  請看以下存儲進程:

  /*SP2*/
  create PROCEDURE DBO.DELUSERALL
  AS
  SET NOCOUNT ON
  BEGIN
  delete from DBO.[USERINFO]
  END
  GO

  該存儲進程刪去USERINFO表中的所有記錄,沒有任何輸入及輸出,調用方法與上面講過的基本相同,只是不用取得記錄集:

  '**通過COMMAND對象調用存儲進程**
  DIM MYCOMM
  SET MYCOMM = SERVER.createOBJECT("ADODB.COMMAND")
  MYCOMM.ACTIVECONNECTION = MYCONSTR    'MYCONSTR是數據庫連接字串
  MYCOMM.COMMANDTEXT  = "DELUSERALL"  '指定存儲進程名
  MYCOMM.COMMANDTYPE  = 4      '表明這是一個存儲進程
  MYCOMM.PREPARED    = TRUE      '要求將SQL命令先行編譯
  MYCOMM.execUTE          '此處不必再取得記錄集
  SET MYCOMM = NOTHING  

  當然也可通過CONNECTION對象或RECORDSET對象調用此類存儲進程,不過建立RECORDSET對象是為了取得記錄集,在沒有返回記錄集的情況下,還是利用COMMAND對象吧。


  3. 有返回值的存儲進程
  在進行類似SP2的操作時,應充分利用SQL SERVER強大的事務處理功能,以維護數據的一致性。并且,我們可能需要存儲進程返回執行情況,為此,將SP2修改如下:

  /*SP3*/
  create PROCEDURE DBO.DELUSERALL
  AS
  SET NOCOUNT ON
  BEGIN
  BEGIN TRANSACTION
  delete from DBO.[USERINFO]
  IF @@ERROR=0
    BEGIN
    COMMIT TRANSACTION
    RETURN 1
    END
  ELSE
    BEGIN
    ROLLBACK TRANSACTION
    RETURN 0
    END    
  RETURN
  END
  GO

  以上存儲進程,在delete順利執行時,返回1,否則返回0,并進行回滾操作。為了在ASP中取得返回值,需要利用PARAMETERS集合來聲明參數:

  '**調用帶有返回值的存儲進程并取得返回值**
  DIM MYCOMM,MYPARA
  SET MYCOMM = SERVER.createOBJECT("ADODB.COMMAND")
  MYCOMM.ACTIVECONNECTION = MYCONSTR    'MYCONSTR是數據庫連接字串
  MYCOMM.COMMANDTEXT  = "DELUSERALL"  '指定存儲進程名
  MYCOMM.COMMANDTYPE  = 4      '表明這是一個存儲進程
  MYCOMM.PREPARED    = TRUE      '要求將SQL命令先行編譯
  '聲明返回值
  SET MYPARA = MYCOMM.createPARAMETER("RETURN",2,4)
  MYCOMM.PARAMETERS.APPEND MYPARA
  MYCOMM.execUTE
  '取得返回值
  DIM RETVALUE
  RETVALUE = MYCOMM(0)  '或RETVALUE = MYCOMM.PARAMETERS(0)
  SET MYCOMM = NOTHING

  在MYCOMM.createPARAMETER("RETURN",2,4)中,各參數的含義如下:
  第一個參數("RETURE")為參數名。參數名可以任意設定,但一般應與存儲進程中聲明的參數名相同。此處是返回值,我習氣上設為"RETURE";
  第二個參數(2),表明該參數的數據類型,具體的類型代碼請參閱ADO參考,以下給出常用的類型代碼:
  ADBIGINT: 20 ;
  ADBINARY : 128 ;
  ADBOOLEAN: 11 ;
  ADCHAR: 129 ;
  ADDBTIMESTAMP: 135 ;
  ADEMPTY: 0 ;
  ADINTEGER: 3 ;
  ADSMALLINT: 2 ;
  ADTINYINT: 16 ;
  ADVARCHAR: 200 ;
  對于返回值,只能取整形,且-1到-99為保留值;
  第三個參數(4),表明參數的性質,此處4表明這是一個返回值。此參數取值的說明如下:
  0 : 類型無法確定; 1: 輸入參數;2: 輸入參數;3:輸入或輸出參數;4: 返回值

  以上給出的ASP代碼,應該說是完整的代碼,也即最復雜的代碼,其實:

  SET MYPARA = MYCOMM.createPARAMETER("RETURN",2,4)
  MYCOMM.PARAMETERS.APPEND MYPARA


  可以簡化為:

  MYCOMM.PARAMETERS.APPEND MYCOMM.createPARAMETER("RETURN",2,4)

  甚至還可以繼續簡化,稍后會做說明。

  對于帶參數的存儲進程,只能使用COMMAND對象調用(也有資料說可通過CONNECTION對象或RECORDSET對象調用,但我沒有試成過)。


4. 有輸入參數和輸出參數的存儲進程
  返回值其實是一種特殊的輸出參數。在大多數情況下,我們用到的是同時有輸入及輸出參數的存儲進程,比如我們想取得用戶信息表中,某ID用戶的用戶名,這時候,有一個輸入參數----用戶ID,和一個輸出參數----用戶名。實現這一功能的存儲進程如下:

  /*SP4*/
  create PROCEDURE DBO.GETUSERNAME
  @USERID INT,
  @USERNAME VARCHAR(40) OUTPUT
  AS
  SET NOCOUNT ON
  BEGIN
  IF @USERID IS NULL RETURN
  select @USERNAME=USERNAME
    from DBO.[USERINFO]
    where USERID=@USERID
  RETURN
  END
  GO

  調用該存儲進程的ASP代碼如下:

  '**調用帶有輸入輸出參數的存儲進程**
  DIM MYCOMM,USERID,USERNAME
  USERID = 1
  SET MYCOMM = SERVER.createOBJECT("ADODB.COMMAND")
  MYCOMM.ACTIVECONNECTION = MYCONSTR    'MYCONSTR是數據庫連接字串
  MYCOMM.COMMANDTEXT  = "GETUSERNAME"   '指定存儲進程名
  MYCOMM.COMMANDTYPE  = 4      '表明這是一個存儲進程
  MYCOMM.PREPARED    = TRUE    '要求將SQL命令先行編譯
  '聲明參數
  MYCOMM.PARAMETERS.APPEND MYCOMM.createPARAMETER("@USERID",3,1,4,USERID)
  MYCOMM.PARAMETERS.APPEND MYCOMM.createPARAMETER("@USERNAME",200,2,40)
  MYCOMM.execUTE
  '取得出參
  USERNAME = MYCOMM(1)
  SET MYCOMM = NOTHING

  在以上代碼中,可以看到,與聲明返回值不同,聲明輸入參數時需要5個參數,聲明輸出參數時需要4個參數。聲明輸入參數時5個參數分別為:參數名、參數數據類型、參數類型、數據長度、參數值。聲明輸出參數時,沒有最后一個參數:參數值。

  需要特別注意的是:在聲明參數時,順序一定要與存儲進程中定義的順序相同,而且各參數的數據類型、長度也要與存儲進程中定義的相同。
  如果存儲進程有多個參數,ASP代碼會顯得繁瑣,可以使用WITH命令簡化代碼:

  '**調用帶有輸入輸出參數的存儲進程(簡化代碼)**
  DIM MYCOMM,USERID,USERNAME
  USERID = 1
  SET MYCOMM = SERVER.createOBJECT("ADODB.COMMAND")
  WITH MYCOMM
  .ACTIVECONNECTION = MYCONSTR    'MYCONSTR是數據庫連接字串
  .COMMANDTEXT  = "GETUSERNAME"   '指定存儲進程名
  .COMMANDTYPE  = 4      '表明這是一個存儲進程
  .PREPARED    = TRUE      '要求將SQL命令先行編譯
  .PARAMETERS.APPEND .createPARAMETER("@USERID",3,1,4,USERID)
  .PARAMETERS.APPEND .createPARAMETER("@USERNAME",200,2,40)
  .execUTE
  END WITH
  USERNAME = MYCOMM(1)
  SET MYCOMM = NOTHING

  假如我們要取得ID為1到10,10位用戶的用戶名,是不是要創建10次COMMAND對象呢?不是的。如果需要多次調用同一存儲進程,只需改變輸入參數,就會得到不同的輸出:

  '**多次調用同一存儲進程**
  DIM MYCOMM,USERID,USERNAME
  USERNAME = ""
  SET MYCOMM = SERVER.createOBJECT("ADODB.COMMAND")
  FOR USERID = 1 TO 10
  WITH MYCOMM
    .ACTIVECONNECTION = MYCONSTR    'MYCONSTR是數據庫連接字串
    .COMMANDTEXT  = "GETUSERNAME"   '指定存儲進程名
    .COMMANDTYPE  = 4      '表明這是一個存儲進程
    .PREPARED    = TRUE      '要求將SQL命令先行編譯
    IF USERID = 1 THEN
    .PARAMETERS.APPEND .createPARAMETER("@USERID",3,1,4,USERID)
    .PARAMETERS.APPEND .createPARAMETER("@USERNAME",200,2,40)
    .execUTE
    ELSE
    '重新給入參賦值(此時參數值不發生變化的入參以及出參不必重新聲明)
    .PARAMETERS("@USERID") = USERID
    .execUTE
    END IF
  END WITH
  USERNAME = USERNAME + MYCOMM(1) + ","   '也許你喜歡用數組存儲
  NEXT
  SET MYCOMM = NOTHING

  通過以上代碼可以看出:重復調用同一存儲進程時,只需為值發生改變的輸入參數重新賦值即可,這一方法在有多個輸入輸出參數,且每次調用時只有一個輸入參數的值發生變化時,可以大大減少代碼量。


  5. 同時具有返回值、輸入參數、輸出參數的存儲進程
  前面說過,在調用存儲進程時,聲明參數的順序要與存儲進程中定義的順序相同。還有一點要特別注意:如果存儲進程同時具有返回值以及輸入、輸出參數,返回值要最先聲明。

  為了演示這種情況下的調用方法,我們改善一下上面的例子。還是取得ID為1的用戶的用戶名,但是有可能該用戶不具有(該用戶已刪除,而USERID是自增長的字段)。存儲進程根據用戶具有與否,返回不同的值。此時,存儲進程和ASP代碼如下:

  /*SP5*/
  create PROCEDURE DBO.GETUSERNAME
  --為了加深對"順序"的印象,將以下兩參數的定義順序顛倒一下
  @USERNAME VARCHAR(40) OUTPUT,
  @USERID INT
  AS
  SET NOCOUNT ON
  BEGIN
  IF @USERID IS NULL RETURN
  select @USERNAME=USERNAME
    from DBO.[USERINFO]
    where USERID=@USERID
  IF @@ROWCOUNT>0
    RETURN 1
  ELSE
    RETURN 0
  RETURN
  END
  GO

  '**調用同時具有返回值、輸入參數、輸出參數的存儲進程**
  DIM MYCOMM,USERID,USERNAME
  USERID = 1
  SET MYCOMM = SERVER.createOBJECT("ADODB.COMMAND")
  WITH MYCOMM
  .ACTIVECONNECTION = MYCONSTR    'MYCONSTR是數據庫連接字串
  .COMMANDTEXT  = "GETUSERNAME"   '指定存儲進程名
  .COMMANDTYPE  = 4      '表明這是一個存儲進程
  .PREPARED    = TRUE      '要求將SQL命令先行編譯
  '返回值要最先被聲明
  .PARAMETERS.APPEND .createPARAMETER("RETURN",2,4)
  '以下兩參數的聲明順序也做相應顛倒
  .PARAMETERS.APPEND .createPARAMETER("@USERNAME",200,2,40)
  .PARAMETERS.APPEND .createPARAMETER("@USERID",3,1,4,USERID)
  .execUTE
  END WITH
  IF MYCOMM(0) = 1 THEN
  USERNAME = MYCOMM(1)
  ELSE
  USERNAME = "該用戶不具有"
  END IF
  SET MYCOMM = NOTHING


6. 同時返回參數和記錄集的存儲進程
  有時候,我們需要存儲進程同時返回參數和記錄集,比如在利用存儲進程分頁時,要同時返回記錄集以及數據總量等參數。以下給出一個進行分頁處理的存儲進程:

  /*SP6*/
  create PROCEDURE DBO.GETUSERLIST
  @IPAGECOUNT INT OUTPUT,   --總頁數
  @IPAGE INT,      --當前頁號
  @IPAGESIZE INT    --每頁記錄數
  AS
  SET NOCOUNT ON
  BEGIN
  --創建臨時表
  create TABLE #T (ID INT IDENTITY,   --自增字段
        USERID INT,
        USERNAME VARCHAR(40))
  --向臨時表中寫入數據
  insert INTO #T
    select USERID,USERNAME from DBO.[USERINFO]
    ORDER BY USERID

  --取得記錄總數
  DECLARE @IRECORDCOUNT INT
  SET @IRECORDCOUNT = @@ROWCOUNT

  --確定總頁數
  IF @IRECORDCOUNT%@IPAGESIZE=0
    SET @IPAGECOUNT=CEILING(@IRECORDCOUNT/@IPAGESIZE)
  ELSE
    SET @IPAGECOUNT=CEILING(@IRECORDCOUNT/@IPAGESIZE)+1

  --若請求的頁號大于總頁數,則顯示最后一頁
  IF @IPAGE > @IPAGECOUNT
    select @IPAGE = @IPAGECOUNT

  --確定當前頁的始末記錄
  DECLARE @ISTART INT  --START RECORD
  DECLARE @IEND INT  --END RECORD
  select @ISTART = (@IPAGE - 1) * @IPAGESIZE
  select @IEND = @ISTART + @IPAGESIZE + 1

  --取當前頁記錄  
  select * from #T where ID>@ISTART AND ID<@IEND

  --刪除臨時表
  drop TABLE #T

  --返回記錄總數
  RETURN @IRECORDCOUNT
  END
  GO

  在上面的存儲進程中,輸入當前頁號及每頁記錄數,返回當前頁的記錄集,總頁數及記錄總數。為了更具典型性,將記錄總數以返回值的形式返回。以下是調用該存儲進程的ASP代碼(具體的分頁操作略去):

  '**調用分頁存儲進程**
  DIM PAGENOW,PAGESIZE,PAGECOUNT,RECORDCOUNT
  DIM MYCOMM,MYRST
  PAGENOW = REQUEST("PN")
  '自定義函數用于驗證自然數
  IF CHECKNAR(PAGENOW) = FALSE THEN PAGENOW = 1
  PAGESIZE = 20
  SET MYCOMM = SERVER.createOBJECT("ADODB.COMMAND")
  WITH MYCOMM
  .ACTIVECONNECTION = MYCONSTR    'MYCONSTR是數據庫連接字串
  .COMMANDTEXT  = "GETUSERLIST"   '指定存儲進程名
  .COMMANDTYPE  = 4      '表明這是一個存儲進程
  .PREPARED    = TRUE    '要求將SQL命令先行編譯
  '返回值(記錄總量)
  .PARAMETERS.APPEND .createPARAMETER("RETURN",2,4)
  '出參(總頁數)
  .PARAMETERS.APPEND .createPARAMETER("@IPAGECOUNT",3,2)
  '入參(當前頁號)
  .PARAMETERS.APPEND .createPARAMETER("@IPAGE",3,1,4,PAGENOW)
  '入參(每頁記錄數)
  .PARAMETERS.APPEND .createPARAMETER("@IPAGESIZE",3,1,4,PAGESIZE)
  SET MYRST = .execUTE
  END WITH
  IF MYRST.STATE = 0 THEN    '未取到數據,MYRST關閉
  RECORDCOUNT = -1
  ELSE
  MYRST.CLOSE  '注意:若要取得參數值,需先關閉記錄集對象
  RECORDCOUNT = MYCOMM(0)
  PAGECOUNT   = MYCOMM(1)
  IF CINT(PAGENOW)>=CINT(PAGECOUNT) THEN PAGENOW=PAGECOUNT
  END IF
  SET MYCOMM = NOTHING

  '以下顯示記錄
  IF RECORDCOUNT = 0 THEN
  RESPONSE.WRITE "無記錄"
  ELSEIF RECORDCOUNT > 0 THEN
  MYRST.OPEN
  DO UNTIL MYRST.EOF
  ......
  LOOP
  '以下顯示分頁信息
  ......
  ELSE  'RECORDCOUNT=-1
  RESPONSE.WRITE "參數錯誤"
  END IF

  對于以上代碼,只有一點需要說明:同時返回記錄集和參數時,若要取得參數,需先將記錄集關閉,使用記錄集時再將其打開。


  7. 返回多個記錄集的存儲進程
  本文最先介紹的是返回記錄集的存儲進程。有時候,需要一個存儲進程返回多個記錄集,在ASP中,如何同時取得這些記錄集呢?為了說明這一問題,在USERINFO表中增加兩個字段:USERTEL及USERMAIL,并設定只有登錄用戶可以查看這兩項內容。

  /*SP7*/
  create PROCEDURE DBO.GETUSERINFO
  @USERID INT,
  @CHECKLOGIN BIT
  AS
  SET NOCOUNT ON
  BEGIN
  IF @USERID IS NULL OR @CHECKLOGIN IS NULL RETURN
  select USERNAME
    from DBO.[USRINFO]
    where USERID=@USERID
  --若為登錄用戶,取USERTEL及USERMAIL
  IF @CHECKLOGIN=1
    select USERTEL,USERMAIL
    from DBO.[USERINFO]
    where USERID=@USERID
  RETURN
  END
  GO

  以下是ASP代碼:

  '**調用返回多個記錄集的存儲進程**
  DIM CHECKLG,USERID,USERNAME,USERTEL,USERMAIL
  DIM MYCOMM,MYRST
  USERID = 1
  'CHECKLOGIN()為自定義函數,判斷訪問者是否登錄
  CHECKLG = CHECKLOGIN()
  SET MYCOMM = SERVER.createOBJECT("ADODB.COMMAND")
  WITH MYCOMM
  .ACTIVECONNECTION = MYCONSTR    'MYCONSTR是數據庫連接字串
  .COMMANDTEXT  = "GETUSERINFO"   '指定存儲進程名
  .COMMANDTYPE  = 4      '表明這是一個存儲進程
  .PREPARED    = TRUE      '要求將SQL命令先行編譯
  .PARAMETERS.APPEND .createPARAMETER("@USERID",3,1,4,USERID)
  .PARAMETERS.APPEND .createPARAMETER("@CHECKLOGIN",11,1,1,CHECKLG)
  SET MYRST = .execUTE
  END WITH
  SET MYCOMM = NOTHING

  '從第一個記錄集中取值
  USERNAME = MYRST(0)
  '從第二個記錄集中取值
  IF NOT MYRST IS NOTHING THEN
  SET MYRST = MYRST.NEXTRECORDSET()
  USERTEL  = MYRST(0)
  USERMAIL = MYRST(1)
  END IF
  SET MYRST = NOTHING

  以上代碼中,利用RECORDSET對象的NEXTRECORDSET方法,取得了存儲進程返回的多個記錄集。


  至此,針對ASP調用存儲進程的各種情況,本文已做了較為全面的說明。最后說一下在一個ASP程序中,調用多個存儲進程的不同方法。
  在一個ASP程序中,調用多個存儲進程至少有以下三種方法是可行的:

  1. 創建多個COMMAND對象

  DIM MYCOMM
  SET MYCOMM = SERVER.createOBJECT("ADODB.COMMAND")
  '調用存儲進程一
  ......
  SET MYCOMM = NOTHING
  SET MYCOMM = SERVER.createOBJECT("ADODB.COMMAND")
  '調用存儲進程二
  ......
  SET MYCOMM = NOTHING
  ......

   2. 只創建一個COMMAND對象,結束一次調用時,清除其參數

  DIM MYCOMM
  SET MYCOMM = SERVER.createOBJECT("ADODB.COMMAND")
  '調用存儲進程一
  .....
  '清除參數(假設有三個參數)
  MYCOMM.PARAMETERS.delete 2
  MYCOMM.PARAMETERS.delete 1
  MYCOMM.PARAMETERS.delete 0
  '調用存儲進程二并清除參數
  ......
  SET MYCOMM = NOTHING

  此時要注意:清除參數的順序與參數聲明的順序相反,原因嘛,我也不知道。

  3. 利用PARAMETERS數據集合的REFRESH方法重置PARAMETER對象

  DIM MYCOMM
  SET MYCOMM = SERVER.createOBJECT("ADODB.COMMAND")
  '調用存儲進程一
  .....
  '重置PARAMETERS數據集合中包含的所有PARAMETER對象
  MYCOMM.PARAMETERS.REFRESH
  '調用存儲進程二
  .....
  SET MYCOMM = NOTHING

  一般以為,重復創建對象是效率較低的一種方法,但是經測試(測試工具為MICROSOFT APPLICATION CENTER TEST),結果出人意料:
  方法2 >= 方法1 >> 方法3
  方法2的運行速度大于等于方法1(最多可高4%左右),這兩種方法的運行速度遠大于方法3(最多竟高達130%),所以建議在參數多時,采用方法1,在參數較少時,采用方法2。

  花了一天的時間,終于把我對于在ASP中調用存儲進程的一些粗淺的經驗形成了文字。這其中,有些是我只知其果而不明其因的,有些可能是錯誤的,但是,這些都是經過我親身實踐的,各位看官批判地接受吧。


該文章在 2022/6/21 20:35:45 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved