スポンサーリンク

【SQL Server】プロシージャの作成日と更新日を取得する(sys.procedures・sys.objects)

SQLSERVER DB

SQL Server で、プロシージャの作成日と更新日を取得する方法をまとめておきます。

仕事で SQL Server を扱うことになり、プロシージャがいつ更新されたのかを確かめる必要があったんです。カタログビューの sys.procedures を見れば、create_date(作成日)と modify_date(更新日)がすぐに取れます。

環境

  • SQL Server 2025(RTM-CU9、17.0.5005.3)Enterprise Developer Edition
  • OS:Ubuntu 22.04.5 LTS(SQL Server が動いている OS)
  • 実行:sqlcmd(mssql-tools18)

動作確認は 2026 年 10 月 10 日です。

試すために作ったもの

テーブル・ビュー・関数と、プロシージャを 2 つ作りました。

CREATE DATABASE t008db;
GO
USE t008db;
GO
CREATE TABLE dbo.orders (id int PRIMARY KEY, ordered_at datetime2(0) NOT NULL);
GO
CREATE VIEW dbo.v_orders AS SELECT id, ordered_at FROM dbo.orders;
GO
CREATE FUNCTION dbo.fn_add_tax (@price int) RETURNS int AS BEGIN RETURN @price * 110 / 100; END;
GO
CREATE PROCEDURE dbo.usp_get_orders AS SELECT id, ordered_at FROM dbo.orders;
GO
CREATE PROCEDURE dbo.usp_add_order @id int AS INSERT INTO dbo.orders (id, ordered_at) VALUES (@id, SYSDATETIME());
GO

5 秒ほど待ってから、usp_get_orders だけを変更しました。

CREATE OR ALTER PROCEDURE dbo.usp_get_orders AS SELECT id, ordered_at FROM dbo.orders ORDER BY ordered_at DESC;
GO

この記事の SQL は、どれも USE t008db; のあとに実行しています(以降は USE を省略しています)。

sys.procedures で取得する

プロシージャの作成日と更新日は、これで取れます。

SELECT SCHEMA_NAME(schema_id) AS schema_name, name, create_date, modify_date
FROM sys.procedures
ORDER BY modify_date DESC;
GO
schema_name name create_date modify_date
----------- ---- ----------- -----------
dbo usp_get_orders 2026-10-10 00:14:34.970 2026-10-10 00:14:40.613
dbo usp_add_order 2026-10-10 00:14:34.977 2026-10-10 00:14:34.977

(2 rows affected)

変更した usp_get_orders だけ、modify_date が 6 秒ほど後になっていますね。公式ドキュメントでは、modify_date は「ALTER で最後に変更した日時」と説明されています。今回の CREATE OR ALTER でも、ちゃんと更新されました。

sys.procedures には、プロシージャしか入っていません。なので、WHERE で絞り込まなくて OK です。スキーマ名は SCHEMA_NAME(schema_id) で取れます。

nano:正確には、sys.procedures には CLR のプロシージャ(PC)や拡張ストアドプロシージャ(X)も入ります。T-SQL で書いたプロシージャだけにしたいときは、WHERE type = 'P' を付けます。

sys.objects で取得する

テーブルやビューも含めた全部のオブジェクトは、sys.objects に入っています。プロシージャは type = 'P' です。

SELECT name, type, create_date, modify_date
FROM sys.objects
WHERE type = 'P'
ORDER BY name;
GO
name type create_date modify_date
---- ---- ----------- -----------
usp_add_order P  2026-10-10 00:14:34.977 2026-10-10 00:14:34.977
usp_get_orders P  2026-10-10 00:14:34.970 2026-10-10 00:14:40.613

(2 rows affected)

sys.objects はテーブルではなく、カタログビューです。type の種類は、次の SQL で一覧にできます。

SELECT type, type_desc, is_ms_shipped, COUNT(*) AS cnt
FROM sys.objects
GROUP BY type, type_desc, is_ms_shipped
ORDER BY is_ms_shipped, type;
GO
type type_desc is_ms_shipped cnt
---- --------- ------------- ---
FN SQL_SCALAR_FUNCTION 0 1
P  SQL_STORED_PROCEDURE 0 2
PK PRIMARY_KEY_CONSTRAINT 0 1
U  USER_TABLE 0 1
V  VIEW 0 1
IT INTERNAL_TABLE 1 43
S  SYSTEM_TABLE 1 72
SQ SERVICE_QUEUE 1 3

(8 rows affected)

作った覚えのない IT・S・SQ が、ずらっと出てきました。これは is_ms_shipped = 1、つまり SQL Server が内部で作ったものです。自分で作ったものだけを見たいときは、is_ms_shipped = 0 で絞ります。

最近更新したものだけを探す

「ここ 1 週間で変わったものは?」を調べたいときは、modify_date で絞り込みます。

SELECT name, type_desc, modify_date
FROM sys.objects
WHERE is_ms_shipped = 0
  AND modify_date >= DATEADD(day, -7, GETDATE())
ORDER BY modify_date DESC;
GO
name type_desc modify_date
---- --------- -----------
usp_get_orders SQL_STORED_PROCEDURE 2026-10-10 00:14:40.613
usp_add_order SQL_STORED_PROCEDURE 2026-10-10 00:14:34.977
fn_add_tax SQL_SCALAR_FUNCTION 2026-10-10 00:14:34.963
v_orders VIEW 2026-10-10 00:14:34.953
PK__orders__3213E83F716061A4 PRIMARY_KEY_CONSTRAINT 2026-10-10 00:14:34.947
orders USER_TABLE 2026-10-10 00:14:34.943

(6 rows affected)

プロシージャの中身も見る

更新日が分かったら、中身も見たくなりますよね。OBJECT_DEFINITION で、定義の SQL を取り出せます。

SELECT OBJECT_DEFINITION(OBJECT_ID(N'dbo.usp_get_orders')) AS definition;
GO
definition
----------
CREATE   PROCEDURE dbo.usp_get_orders AS SELECT id, ordered_at FROM dbo.orders ORDER BY ordered_at DESC;


(1 rows affected)

CREATE OR ALTER で作ったのに、CREATE PROCEDURE になっています。OR ALTER の部分が、しれっと空白に置き換わっていました。

まとめて見たいときは、sys.sql_modules の definition 列を結合します。

SELECT p.name, m.definition
FROM sys.procedures AS p
JOIN sys.sql_modules AS m ON m.object_id = p.object_id
ORDER BY p.name;
GO
name definition
---- ----------
usp_add_order CREATE PROCEDURE dbo.usp_add_order @id int AS INSERT INTO dbo.orders (id, ordered_at) VALUES (@id, SYSDATETIME());

usp_get_orders CREATE   PROCEDURE dbo.usp_get_orders AS SELECT id, ordered_at FROM dbo.orders ORDER BY ordered_at DESC;


(2 rows affected)

ハマったこと

DROP して作り直すと、作成日も変わる

usp_add_order を DROP して、同じ内容で作り直してみました。

DROP PROCEDURE dbo.usp_add_order;
GO
CREATE PROCEDURE dbo.usp_add_order @id int AS INSERT INTO dbo.orders (id, ordered_at) VALUES (@id, SYSDATETIME());
GO
SELECT name, create_date, modify_date
FROM sys.procedures
ORDER BY name;
GO
name create_date modify_date
---- ----------- -----------
usp_add_order 2026-10-10 00:14:55.337 2026-10-10 00:14:55.337
usp_get_orders 2026-10-10 00:14:34.970 2026-10-10 00:14:40.613

(2 rows affected)

usp_add_order の create_date が、作り直した時刻に変わりました。別のオブジェクトとして作り直しているので、当然といえば当然です。

リリースの手順が「DROP してから CREATE」だと、作成日は「最初に作った日」ではなくなります。作成日を当てにするときは、どうやってリリースしているかも確かめておくと安心ですね。

権限がないと、エラーにならずに 0 行になる

権限を何も付けていないユーザー(t008_reader)で、sys.procedures を見てみました。権限を 1 つずつ足しながら試しています。

CREATE USER t008_reader WITHOUT LOGIN;
GO
EXECUTE AS USER = 't008_reader';
SELECT COUNT(*) AS visible_procedures FROM sys.procedures;
REVERT;
GO
GRANT EXECUTE ON dbo.usp_get_orders TO t008_reader;
GO
EXECUTE AS USER = 't008_reader';
SELECT name FROM sys.procedures ORDER BY name;
REVERT;
GO
GRANT VIEW DEFINITION TO t008_reader;
GO
EXECUTE AS USER = 't008_reader';
SELECT name FROM sys.procedures ORDER BY name;
REVERT;
GO
visible_procedures
------------------
0

(1 rows affected)
name
----
usp_get_orders

(1 rows affected)
name
----
usp_add_order
usp_get_orders

(2 rows affected)
付けた権限見えたプロシージャ
なし0 行
usp_get_orders の EXECUTEusp_get_orders だけ
データベースの VIEW DEFINITION2 つとも

権限がなくてもエラーにはならず、黙って 0 行が返ってきます。「プロシージャが 1 つもない」と勘違いしやすいので要注意です。

カタログビューでは、自分が持っているか、何かしらの権限があるものしか見えません。sa のような強い権限は要らなくて、VIEW DEFINITION があれば全部見えました。

まとめ

  • プロシージャの作成日と更新日は、sys.procedures の create_date と modify_date で取れる
  • テーブルやビューも含めるなら sys.objects。自分で作ったものだけなら is_ms_shipped = 0 で絞る
  • ALTER(CREATE OR ALTER も)では更新日だけが変わる。DROP して作り直すと作成日も変わる
  • 権限がないと 0 行になる。全部見るには VIEW DEFINITION 権限があればよい

同じことで困っている方の参考になれば幸いです。

今回は、以上です。

参考資料

あわせて読みたい

タイトルとURLをコピーしました