SQL Server中筛选用户创建视图需同时满足:OBJECTPROPERTY(object_id, 'IsMSShipped') = 0 且 schema_name(schema_id) NOT IN ('sys', 'INFORMATION_SCHEMA');推荐用OBJECT_DEFINITION(object_id)获取定义,并手动拼接CREATE VIEW头部及换行符。

查哪些视图是用户创建的(排除系统视图)
SQL Server 中,sys.views 包含所有视图,但混着系统自带的(比如以 sys 或 dm_ 开头的)。真正要导出的,是那些你或业务账号创建的、非系统 schema 的视图。关键看 schema_id 是否属于用户 schema,而不是 sys 或 INFORMATION_SCHEMA。
实操建议用这个条件过滤:
-
OBJECTPROPERTY(object_id, 'IsMSShipped') = 0—— 排除 SQL Server 自带对象 -
schema_name(schema_id) NOT IN ('sys', 'INFORMATION_SCHEMA')—— 排除系统 schema - 如果只关心特定 schema(比如
dbo),可加schema_name(schema_id) = 'dbo'
用 sp_helptext 或 OBJECT_DEFINITION 提取定义
sp_helptext 是传统方式,但它是结果集输出,不方便批量拼接;更推荐用 OBJECT_DEFINITION(object_id),它返回 nvarchar(max),能直接参与字符串拼接和导出。
注意点:
-
OBJECT_DEFINITION返回的是不含CREATE VIEW前缀的原始定义(SQL Server 2005+ 都支持) - 若视图定义超过 4000 字符,
sp_helptext会分多行返回,而OBJECT_DEFINITION一次性完整返回 - 权限要求:需对视图有
VIEW DEFINITION权限,否则返回NULL
生成带 CREATE VIEW 的完整脚本(含 schema 和换行)
仅靠 OBJECT_DEFINITION 不够——它不包含 CREATE VIEW [schema].[name] 头部,也不处理换行兼容性。得手动拼接,并确保换行符在导出时保留(尤其用 SSMS “结果转文本”时)。
示例查询片段:
SELECT
'CREATE VIEW [' + s.name + '].[' + v.name + '] AS' + CHAR(13) + CHAR(10) +
ISNULL(OBJECT_DEFINITION(v.object_id), '-- ERROR: No definition (permission denied or encrypted)') AS ddl
FROM sys.views v
INNER JOIN sys.schemas s ON v.schema_id = s.schema_id
WHERE OBJECTPROPERTY(v.object_id, 'IsMSShipped') = 0
AND s.name NOT IN ('sys', 'INFORMATION_SCHEMA');
说明:
-
CHAR(13)+CHAR(10)强制回车换行,避免定义挤在一行 -
ISNULL(...)捕获加密视图或权限不足导致的NULL,防止整行消失 - 导出时,在 SSMS 中右键结果 → “选择全部” → “复制”,再粘贴到 .sql 文件即可
导出到文件的替代方案:用 sqlcmd 命令行直出
如果数据量大、或需要定时导出,SSMS 手动复制容易漏行或截断。这时用 sqlcmd 更可靠:
sqlcmd -S localhost -d YourDB -E -Q "SET NOCOUNT ON; SELECT 'CREATE VIEW [' + s.name + '].[' + v.name + '] AS' + CHAR(13) + CHAR(10) + ISNULL(OBJECT_DEFINITION(v.object_id), '') FROM sys.views v JOIN sys.schemas s ON v.schema_id = s.schema_id WHERE OBJECTPROPERTY(v.object_id, 'IsMSShipped') = 0 AND s.name NOT IN ('sys','INFORMATION_SCHEMA')" -o "views_ddl.sql"
关键参数:
-
-E表示 Windows 身份认证;如用 SQL 登录,换成-U user -P pass -
-o指定输出文件路径,内容为纯文本,无列头/分隔线 -
SET NOCOUNT ON防止每条语句返回 “(X 行受影响)” 干扰脚本
加密视图、权限受限视图、或跨库引用的视图定义可能为空,这些地方容易被忽略——得单独检查 OBJECT_DEFINITION 返回值是否为 NULL 或空字符串,不能只看结果行数。










