探索SQL Server元數據(二)

来源:https://www.cnblogs.com/wenBlog/archive/2018/07/17/9324379.html
-Advertisement-
Play Games

背景 上一篇中,我介紹了SQL Server 允許訪問資料庫的元數據,為什麼有元數據,如何使用元數據。這一篇中我會介紹如何進一步找到各種有價值的信息。以觸發器為例,因為它們往往一起很多問題。 那麼如何找到觸發器的數據? 以sys.system_viewsis表開始。讓我們查詢出資料庫中使用觸發器的信 ...


背景

  上一篇中,我介紹了SQL Server 允許訪問資料庫的元數據,為什麼有元數據,如何使用元數據。這一篇中我會介紹如何進一步找到各種有價值的信息。以觸發器為例,因為它們往往一起很多問題。

 

那麼如何找到觸發器的數據?

  以sys.system_viewsis表開始。讓我們查詢出資料庫中使用觸發器的信息。可以告知你當前SQL Server版本中有什麼觸發器。

SELECT schema_name(schema_ID)+'.'+ name

  FROM sys.system_views WHERE name LIKE '%trigger%'
 ----------------------------------------

sys.dm_exec_trigger_stats              

sys.server_trigger_events              

sys.server_triggers                    

sys.trigger_event_types                

sys.trigger_events                     

sys.triggers                           

 

(6 row(s) affected)

  其中sys.triggers看起來信息很多,它又包含什麼列?下麵這個查詢很容易查到:

 SELECT Thecol.name+ ' '+ Type_name(TheCol.system_type_id)

  + CASE WHEN TheCol.is_nullable=1 THEN ' NULL' ELSE ' NOT NULL' END as Column_Information

FROM sys.system_views AS TheView

  INNER JOIN sys.system_columns AS TheCol

    ON TheView.object_ID=TheCol.Object_ID

  WHERE  TheView.name = 'triggers'

  ORDER BY column_ID;

結果如下:

 Column_Information

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

name nvarchar NOT NULL

object_id int NOT NULL

parent_class tinyint NOT NULL

parent_class_desc nvarchar NULL

parent_id int NOT NULL

type char NOT NULL

type_desc nvarchar NULL

create_date datetime NOT NULL

modify_date datetime NOT NULL

is_ms_shipped bit NOT NULL

is_disabled bit NOT NULL

is_not_for_replication bit NOT NULL

is_instead_of_trigger bit NOT NULL

 

因此我們多這個信息有了更好的理解,有了一個目錄的目錄。這個概念有點讓人頭暈,但是另一方面,它也是相當簡單的。我們能夠查出元數據,再找個查詢中,需要做的就是改變這個單詞‘triggers’來查找你想要的視圖名稱。.

在2012及其以後版本,可以使用一個新的表值函數極大地簡化上述查詢,並可以避免各種連接。在下麵的查詢中,我們將查找sys.triggers 視圖 中的列。可以使用相同的查詢通過更改字元串中的對象名稱來獲取任何視圖的定義。

 SELECT name+ ' '+ system_type_name

  + CASE WHEN is_nullable=1 THEN ' NULL' ELSE ' NOT NULL' END as Column_Information

FROM sys.dm_exec_describe_first_result_set

  ( N'SELECT * FROM sys.triggers;', NULL, 0) AS f

  ORDER BY column_ordinal;

查詢結果如下:

 Column_Information

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

name nvarchar(128) NOT NULL

object_id int NOT NULL

parent_class tinyint NOT NULL

parent_class_desc nvarchar(60) NULL

parent_id int NOT NULL

type char(2) NOT NULL

type_desc nvarchar(60) NULL

create_date datetime NOT NULL

modify_date datetime NOT NULL

is_ms_shipped bit NOT NULL

is_disabled bit NOT NULL

is_not_for_replication bit NOT NULL

is_instead_of_trigger bit NOT NULL

 

sys.dm_exec_describe_first_result_set函數的最大優勢在於你能看到任何結果的列,不僅僅是表和視圖、存儲過程或者貶值函數。

為了查出任何列的信息,你可以使用稍微修改的版本,只需要改變代碼中的字元串'sys.triggers'即可,如下:

 Declare @TheParamater nvarchar(255)

Select @TheParamater = 'sys.triggers'

Select @TheParamater = 'SELECT * FROM ' + @TheParamater

SELECT

  name+ ' '+ system_type_name

  + CASE WHEN is_nullable=1 THEN ' NULL' ELSE ' NOT NULL' END as Column_Information

FROM sys.dm_exec_describe_first_result_set

  ( @TheParamater, NULL, 0) AS f

  ORDER BY column_ordinal;

但是當然一個觸發器是首先是一個對象,因此一定在sys.objects?

  在我們使用sys.triggers的信息之前,需要來重覆一遍,所有的資料庫對象都存在於sys.objects中,在SQL Server 中的對象包括以下:聚合的CLR函數,check 約束,SQL標量函數,CLR標量函數,CLR表值函數,SQL內聯表值函數,內部表,SQL存儲過程,CLR存儲過程,計劃指南,主鍵約束,老式規則,複製過濾程式,系統基礎表,同義詞,序列對象,服務隊列,CLR DML 觸發器,SQL表值函數,表類型,用戶自定義表,唯一約束,視圖和擴展存儲過程等。

  觸發器是對象所以基礎信息一定保存在sys.objects。不走運的是,有時我們需要額外的信息,這些信息可以通過目錄視圖查詢。這些額外數據有是什麼呢?

 

  修改我們使用過的查詢,來查詢sys.triggers的列,這次我們會看到額外信息。這些額外列是來自於sys.objects。

 SELECT coalesce(trigger_column.name,'NOT INCLUDED') AS In_Sys_Triggers,

       coalesce(object_column.name,'NOT INCLUDED') AS In_Sys_Objects

FROM

 (SELECT Thecol.name

  FROM sys.system_views AS TheView

    INNER JOIN sys.system_columns AS TheCol

      ON TheView.object_ID=TheCol.Object_ID

  WHERE  TheView.name = 'triggers') trigger_column

FULL OUTER JOIN

 (SELECT Thecol.name

  FROM sys.system_views AS TheView

    INNER JOIN sys.system_columns AS TheCol

      ON TheView.object_ID=TheCol.Object_ID

  WHERE  TheView.name = 'objects') object_column

ON trigger_column.name=object_column.name

查詢結果:

In_Sys_Triggers                In_Sys_Objects

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

name                           name

object_id                      object_id

NOT INCLUDED                   principal_id

NOT INCLUDED                   schema_id

NOT INCLUDED                   parent_object_id

type                           type

type_desc                      type_desc

create_date                    create_date

modify_date                    modify_date

is_ms_shipped                  is_ms_shipped

NOT INCLUDED                   is_published

NOT INCLUDED                   is_schema_published

is_not_for_replication         NOT INCLUDED

is_instead_of_trigger          NOT INCLUDED

parent_id                      NOT INCLUDED

is_disabled                    NOT INCLUDED

parent_class                   NOT INCLUDED

parent_class_desc              NOT INCLUDED

 

以上這些讓我們知道在sys.triggers的額外信息,但是因為它始終是表的子對象,所以有些不相關信息是不會展示在這些指定的視圖或者sys.triggers中的。現在就要帶大家去繼續找找這些信息。

觸發器的問題

  觸發器是有用的,但是因為它們在SSMS對象資源管理器窗格中不是可見的,所以一般用來提醒錯誤。觸發器有時候會有些微妙的地方讓其出問題,比如,當導入過程中禁用了觸發器,並且由於某些原因他們沒有重啟。

下麵是一個關於觸發器的簡要提醒:

  觸發器可以在視圖,表或者伺服器上,任何這些對象上都可以有超過1個觸發器。普通的DML觸發器能被定義來執行替代一些數據修改(Insert,Update或者Delete)或者在數據修改之後執行。每一個觸發器與只與一個對象管理。DDL觸發器與資料庫關聯或者被定義在伺服器級別,這類觸發器一般在Create,Alter或者Drop這類SQL語句執行後觸發。

  像DML觸發器一樣,可以有多個DDL觸發器被創建在同一個T-SQL語句上。一個DDL觸發器和語句觸發它的語句在同一個事務中運行,所以除了Alter DATABASE之外都可以被回滾。DDL觸發器運行在T-SQL語句執行完畢後,也就是不能作為Instead OF觸發器使用。

  兩種觸發器都與事件相關,在DML觸發器中,包含INSERT, UPDATE, 和DELETE,然而很多事件都可以與DDL觸發器關聯,稍後我們將瞭解。

在資料庫中列出觸發器

那麼怎麼獲取觸發器列表?下麵我在AdventureWorks資料庫中進行查詢,註意該庫的視圖中沒有觸發器。

第一個查詢所有信息都在sys.triggers 的目錄視圖中。

SELECT

  name AS TriggerName,

  coalesce(object_schema_name(parent_ID)+'.'

    +object_name(parent_ID),'Database ('+db_name()+')') AS TheParent

FROM sys.triggers;

 

TriggerName                    TheParent

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

ddlDatabaseTriggerLog          Database (AdventureWorks2012)          

dEmployee                      HumanResources.Employee                

iuPerson                       Person.Person                          

iPurchaseOrderDetail           Purchasing.PurchaseOrderDetail         

uPurchaseOrderDetail           Purchasing.PurchaseOrderDetail         

uPurchaseOrderHeader           Purchasing.PurchaseOrderHeader         

iduSalesOrderDetail            Sales.SalesOrderDetail                 

uSalesOrderHeader              Sales.SalesOrderHeader                 

dVendor                        Purchasing.Vendor                      

iWorkOrder                     Production.WorkOrder                   

uWorkOrder                     Production.WorkOrder   

  我使用元數據函數db_name()使SQL保持簡單。db_name()告訴我資料庫的名稱。object_schema_name()用來查詢object_ID代表的對象的架構,以及object_name()查詢對象名稱。這些對對象的引用指向觸發器的所有者,觸發器可以是資料庫本身,也可以是表:伺服器觸發器有自己的系統視圖,稍後我會展示。

如果想要看到所有觸發器,那麼我們最好使用sys.objects 視圖:

SELECT name as TriggerName, object_schema_name(parent_object_ID)+'.'

    +object_name(parent_object_ID) AS TheParent

            FROM   sys.objects

           WHERE  OBJECTPROPERTYEX(object_id,'IsTrigger') = 1

 

註意,輸出不包含資料庫級別的觸發器,因為所有的DML觸發器都在sys.objects視圖中,但是你會漏掉在sys.triggers視圖中的觸發器。

上面查詢結果:

name                           TheParent

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

dEmployee                      HumanResources.Employee

iuPerson                       Person.Person

iPurchaseOrderDetail           Purchasing.PurchaseOrderDetail

uPurchaseOrderDetail           Purchasing.PurchaseOrderDetail

uPurchaseOrderHeader           Purchasing.PurchaseOrderHeader

iduSalesOrderDetail            Sales.SalesOrderDetail

uSalesOrderHeader              Sales.SalesOrderHeader

dVendor                        Purchasing.Vendor

iWorkOrder                     Production.WorkOrder

uWorkOrder                     Production.WorkOrder

 

我的表和視圖有多少個觸發器?

我想知道每個表有多少個觸發器,並且什麼情況下觸發它們。下麵我們列出了具有觸發器的表以及每個事件的觸發器數量。每個表或者視圖對於觸發器行為都有一個INSTEAD OF 觸發器,可能是UPDATE, DELETE, 或者 INSERT

。但是一個表可以有多個AFTER觸發器行為。這些將展示在下麵的查詢中(排除視圖):

SELECT

convert(CHAR(32),coalesce(object_schema_name(parent_ID)+'.'

    +object_name(parent_ID),'Database ('+db_name()+')')) AS 'Table', triggers,[KD1] [AC2] 

convert(SMALLINT,objectpropertyex(parent_ID, N'TABLEDeleteTriggerCount')) AS 'Delete',

convert(SMALLINT,objectpropertyex(parent_ID, N'TABLEInsertTriggerCount')) AS 'Insert',

convert(SMALLINT,objectpropertyex(parent_ID, N'TABLEUpdateTriggerCount')) AS 'Update'

FROM (SELECT count(*) AS triggers, parent_ID FROM sys.triggers

      WHERE objectpropertyex(parent_ID, N'IsTable') =1

         GROUP BY parent_ID

          )TablesOnly;

--查詢結果如下:

Table                            triggers    Delete Insert Update

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

Purchasing.Vendor                1           0      0      0

Production.WorkOrder             2           0      1      1

Purchasing.PurchaseOrderDetail   2           0      1      1

Purchasing.PurchaseOrderHeader   1           0      0      1

Sales.SalesOrderDetail           1           1      1      1

HumanResources.Employee          1           0      0      0

Sales.SalesOrderHeader           1           0      0      1

Person.Person                    1           0      1      1

 

(8 row(s) affected)

如果超過一個觸發器被觸發在一個表上,它們不保證順序,當然也可以使用sp_settriggerorder來控制順序。通過使用objectpropertyex()元數據函數,需要根據事件輸入參數‘ExecIsLastDeleteTrigger’, ‘ExecIsLastInsertTrigger’ 或者 ‘ExecIsLastUpdateTrigger’來確認誰是最後一個執行的觸發器 。為了得到第一個觸發器,酌情使用ObjectPropertyEx() 元數據函數,需要輸入參數 ‘ExecIsFirstDeleteTrigger’, ‘ExecIsFirstInsertTrigger’ 或者 ‘ExecIsFirstUpdateTrigger’。

因此我們現在知道了表有哪些觸發器,哪些事件觸發這些觸發器。可以使用objectpropertyex()元數據函數,這個函數返回很多不同信息,根據指定的參數不同。通過查看MSDN中的文檔,查看其中的一個文檔是否有助於元數據查詢,總是值得檢查的。

觸發器何時觸發事件?

讓我們看一下這些觸發器,DML觸發器可以在所有其他時間發生後觸發,但是可以在約束被處理前並且觸發INSTEAD OF觸發動作。下麵我們就來看看所有的觸發的到底是AFTER 還是INSTEAD OF 觸發器,有事什麼時間觸發了觸發器。

/* 列出觸發器,無論它們是否啟用,以及觸發器事件。*/

SELECT

  convert(CHAR(25),name) AS triggerName,

  convert(CHAR(32),coalesce(object_schema_name(parent_ID)+'.'

    +object_name(parent_ID),'Database ('+db_name()+')')) AS TheParent,

       is_disabled,

       CASE WHEN is_instead_of_trigger=1 THEN 'INSTEAD OF ' ELSE 'AFTER ' END

       +Stuff (--get a list of events for each trigger

        (SELECT ', '+type_desc FROM sys.trigger_events te

           WHERE te.object_ID=sys.triggers.object_ID

         FOR XML PATH(''), TYPE).value('.', 'varchar(max)'),1,2,'') AS events

 FROM sys.triggers;

結果如下:

triggerName               TheParent                        is_disabled events

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

ddlDatabaseTriggerLog     Database (AdventureWorks2012)    1           AFTER CREATE_TABLE, ALTER_TABLE, DROP_TABLE, CREATE_VIEW, ALTER_VIEW, DROP_VIEW, CREATE_INDEX, ALTER_INDEX, DROP_INDEX, CREATE_XML_INDEX, ALTER_FULLTEXT_INDEX, CREATE_FULLTEXT_INDEX, DROP_FULLTEXT_INDEX, CREATE_SPATIAL_INDEX, CREATE_STATISTICS, UPDATE_STAT

t_AB                      dbo.AB                           0           INSTEAD OF INSERT

dEmployee                 HumanResources.Employee          0           INSTEAD OF DELETE

iuPerson                  Person.Person                    0           AFTER INSERT, UPDATE

iPurchaseOrderDetail      Purchasing.PurchaseOrderDetail   0           AFTER INSERT

uPurchaseOrderDetail      Purchasing.PurchaseOrderDetail   0           AFTER UPDATE

uPurchaseOrderHeader      Purchasing.PurchaseOrderHeader   0           AFTER UPDATE

iduSalesOrderDetail       Sales.SalesOrderDetail           0           AFTER INSERT, UPDATE, DELETE

uSalesOrderHeader         Sales.SalesOrderHeader           0           AFTER UPDATE

dVendor                   Purchasing.Vendor                0           INSTEAD OF DELETE

iWorkOrder                Production.WorkOrder             0           AFTER INSERT

uWorkOrder                Production.WorkOrder             0           AFTER UPDATE

 

As you will notice, we used a FOR XML PATH(‘’) trick here to make a list of the events for each trigger to make it easier to read. These events were pulled from the sys.trigger_events view using a correlated subquery.

註意到我們使用了FOR XML PATH(‘’) 來列出事件的每一個觸發器,更容易讀取理解。sys.trigger_events使用相關子查詢來查詢這些事件。

觸發器的多長?

許多資料庫人員不贊成冗長觸發器的定義,但他們可能會發現,根據定義的長度排序的觸發器列表是研究資料庫的一種有用方法。

SELECT convert(CHAR(32),coalesce(object_schema_name(t.object_ID)+'.','')

    +name) AS TheTrigger,

       convert(CHAR(32),coalesce(object_schema_name(parent_ID)+'.'

    +object_name(parent_ID),'Database ('+db_name()+')')) AS theParent,

       len(definition) AS length --the length of the definition

FROM sys.SQL_modules m

  INNER JOIN sys.triggers t

    ON t.object_ID=m.object_ID

ORDER BY length DESC;

訪問sys.SQL_modules視圖可以查看觸發器定義的SQL DDL,並按大小順序列出它們,最上面是最大的。

結果:

TheTrigger                       theParent                        length

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

Sales.iduSalesOrderDetail        Sales.SalesOrderDetail           3666

Sales.uSalesOrderHeader          Sales.SalesOrderHeader           2907

Purchasing.uPurchaseOrderDetail  Purchasing.PurchaseOrderDetail   2657

Purchasing.iPurchaseOrderDetail  Purchasing.PurchaseOrderDetail   1967

Person.iuPerson                  Person.Person                    1498

ddlDatabaseTriggerLog            Database (AdventureWorks2012)    1235

Purchasing.dVendor               Purchasing.Vendor                1103

Production.uWorkOrder            Production.WorkOrder             1103

Purchasing.uPurchaseOrderHeader  Purchasing.PurchaseOrderHeader   1085

Production.iWorkOrder            Production.WorkOrder             1011

HumanResources.dEmployee         HumanResources.Employee          604

 

好吧,我可能太挑剔了,不太喜歡太長的,但是邏輯有時候會很長。事實上,前三名在我看來是不可靠的,儘管我總是傾向於儘可能少地使用觸發器。

這些觸發器訪問了多少對象

在代碼中,每個觸發器要訪問多少對象(比如表和函數)?

我們只需要檢查表達式依賴項。這個查詢使用一個視圖來列出“軟”依賴項(如觸發器、視圖和函數)。

SELECT coalesce(object_schema_name(parent_id)

          +'.','')+convert(CHAR(32),name) AS TheTrigger,

          count(*) AS Dependencies

FROM sys.triggers

INNER JOIN sys.SQL_Expression_dependencies

ON [referencing_id]=object_ID

GROUP BY name, parent_id

ORDER BY count(*) DESC;
--結果:

TheTrigger                               Dependencies

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

Sales.iduSalesOrderDetail                7

Sales.uSalesOrderHeader                  7

Purchasing.iPurchaseOrderDetail          5

Purchasing.uPurchaseOrderDetail          5

Purchasing.uPurchaseOrderHeader          3

Production.iWorkOrder                    3

Production.uWorkOrder                    3

dbo.t_AB                                 2

Purchasing.dVendor                       2

Person.iuPerson                          2

ddlDatabaseTriggerLog                    1

 

居然有兩個觸發器有7個依賴!讓我們就Sales.iduSalesOrderDetail來實際看一下,有哪些依賴。

特定觸發器訪問或者寫入哪些對象?

我們可以列出觸發器在代碼中引用的所有對象

SELECT

  convert(char(32),name) as TheTrigger,

  convert(char(32),coalesce([referenced_server_name]+'.','')

            +coalesce([referenced_database_name]+'.','')

       +coalesce([referenced_schema_name]+'.','')+[referenced_entity_name])
     as referencedObject

FROM sys.triggers

INNER JOIN sys.SQL_Expression_dependencies

ON [referencing_id]=object_ID

WHERE name LIKE 'iduSalesOrderDetail';

--查詢結果:

TheTrigger                       referencedObject

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

iduSalesOrderDetail              Sales.Customer                 

iduSalesOrderDetail              Person.Person                  

iduSalesOrderDetail              Sales.SalesOrderDetail         

iduSalesOrderDetail              Sales.SalesOrderHeader          

iduSalesOrderDetail              Production.TransactionHistory  

iduSalesOrderDetail              dbo.uspLogError                

iduSalesOrderDetail              dbo.uspPrintError

 

觸發器里有什麼代碼?

現在讓我們通過檢查觸發器的源代碼來確認這一點。.

SELECT OBJECT_DEFINITION ( object_id('sales.iduSalesOrderDetail') ); 

我們之前的查詢是正確的,掃描源碼可知所有的依賴項。大量依賴項表名對於資料庫的重構等需要非常小心,例如,修改一個基礎表的列。

據需要做什麼,您可能希望檢查來自元數據視圖的定義,而不是使用OBJECT_DEFINITION函數。

 SELECT definition

FROM sys.SQL_modules m

  INNER JOIN sys.triggers t

    ON t.object_ID=m.object_ID

WHERE t.object_ID=object_id('sales.iduSalesOrderDetail');

搜索觸發器的代碼

There are always plenty of ways of using the metadata views and functions. I wonder if all these triggers are executing that uspPrintError procedure?

有很多使用元數據視圖和函數的方法。想知道是否所有這些觸發器都執行uspPrintError存儲過程?

/* 在所有觸發器中搜索字元串 */

 

SELECT convert(CHAR(32),coalesce(object_schema_name(object_ID)+'.','')

    +name) AS TheTrigger, '...'+substring(definition, hit-20,120) +'...'

FROM

  (SELECT name, definition, t.object_ID, charindex('EXECUTE [dbo].[uspPrintError]',definition) AS hit

   FROM sys.SQL_modules m

     INNER JOIN sys.triggers t

       ON t.object_ID=m.object_ID)f

WHERE hit>0; 

 

結果如圖:

 

8個引用正在執行這個過程。我們在sys.SQL_modules中搜索了所有的定義可以找到一個特定的字元串,這種方式很慢很暴力,但是它是有效的!

在所有對象中搜索字元串

我想知道除了觸發器之外是否還有其他對象調用這個過程?我們稍微修改查詢以搜索sys.objects視圖,而不是sys.triggers,以搜索所有具有與之關聯的代碼的對象。我們還需要顯示對象的類型

/* 在所有對象中搜索字元串 */

 SELECT convert(CHAR(32),coalesce(object_schema_name(object_ID)+'.','')

    +object_name(object_ID)) AS TheObject, type_desc, '...'+substring(definition,hit-20,120)+'...' as TheExtract

FROM

  (SELECT  type_desc, definition, o.object_ID, charindex('uspPrintError',definition) AS hit

   FROM sys.SQL_modules m

     INNER JOIN sys.objects o

       ON o.object_ID=m.object_ID)f

WHERE hit>0; 

查詢結果如下圖:

 From this output we can see that, other than the procedure itself where it is defined, and the triggers, only dbo.uspLogError is executing the uspPrintError procedure. (see the first column, second line down)

從這個輸出中我們可以看到,除了在定義它的過程本身之外,還有觸發器,只有dbo.uspLogError正在執行uspPrintError過程。(見第一列,第二行往下)

列出伺服器級觸發器及其定義

我們可以通過系統視圖瞭解它們嗎?嗯,是的。以下是列出伺服器觸發器及其定義的語句

 SELECT name, definition

FROM sys.server_SQL_modules m

  INNER JOIN sys.server_triggers t

ON t.object_ID=m.object_ID; 

註意,只能看到有許可權看的觸發器

總結

  本文討論過觸發器,並且你能查出觸發器,以及潛在的問題。這裡並沒有針對關於觸發器的查詢提供一個全面的工具箱,因為我只是使用觸發器作為示例來展示在查詢系統視圖時可能使用的一些技術。在我們學習了索引、列和參數之後,我們將回到觸發器,並瞭解了編寫訪問系統視圖和information schema視圖的查詢的一些日常用途。表是元數據的許多方面的基礎。它們是幾種類型的對象的父類,其他元數據如索引是表的屬性。我們正在慢慢地努力去發現所有關於表的信息。期待下期


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • CRONTAB是一個用於設置周期性被執行的任務的工具,有了它,我們就可以從定時工作中解放出來。 一 : 檢查CRONTAB服務 1. 檢查CRONTAB工具是否已經在主機上安裝 : crontab -l (當然後面會介紹它真正的用途) 2. 檢查CRONTAB服務是否已經啟動 : service c ...
  • 1. 我的環境: 兩臺電腦,分別記為PC1和PC2,PC1有線或者無線連在路由器上,PC2無線連在同一個路由器上。(當然,我的PC1是win10系統,PC2是win7系統) 2. PC1只要一遠程連接PC2,就造成PC2的無線斷開,進而導致遠程桌面連接失敗。 至於原因,我猜測是當PC2電腦被遠程桌面 ...
  • yum 配置源 1 .打開 vi /etc/yum.repos.d/CentOS-Base.repo 註:yum預設載入這個文件 2.刪除 /etc/yum.repos.d/CentOS-Base.repo 裡面的文件內容 (1)使用#dd刪除 (2)echo > /etc/yum.repos.d/ ...
  • 基於CentOS-6.10-x86_64-minimal.iso定製自己的iso,實現自動化安裝,並攜帶定製化軟體做好初始化,適應於CentOS6系列。 ...
  • cd命令:切換目錄 (1)切換到目錄 /usr/local cd /usr/local (2)去到目前的上層目錄 cd .. (3)回到自己的主文件夾 cd ~ ls命令:查看文件與目錄 (4)查看目錄/usr下所有的文件 cd /usr ls -al mkdir命令:新建新目錄 (5)進入/tmp ...
  • [20180718]拷貝數據文件從dg庫.txt1.測試環境:SCOTT@book> @ ver1PORT_STRING VERSION BANNER x86_64/Linux 2.4.xx 11.2.0.4.0 Oracle Database 11g Enterprise Edition Rele ...
  • 占座 ...
  • UNION用於把來自許多SELECT語句的結果組合到一個結果集合中,也叫聯合查詢。 在多個 SELECT 語句中,第一個 SELECT 語句中被使用的欄位名稱將被用於結果的欄位名稱。 當使用 UNION 時,MySQL 會把結果集中重覆的記錄刪掉,而使用 UNION ALL ,MySQL 會把所有的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...