1. 金蝶K3数据库架构解析
作为国内主流ERP系统之一,金蝶K3采用典型的三层架构设计,数据存储层主要依赖SQL Server关系型数据库。系统运行时会产生超过2000张数据表,这些表通过主外键关系构成完整的业务逻辑网络。理解这些基础数据表的结构,是进行二次开发、数据分析和系统运维的重要前提。
从技术实现角度看,K3的数据表命名遵循"模块前缀_业务描述"的规则。例如:
- t_ICItem 表示基础资料模块的物料主表
- t_Organization 存储组织架构信息
- t_Voucher 是总账模块的凭证主表
重要提示:直接操作生产环境数据库存在风险,建议在测试环境进行SQL验证,并做好完整备份
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心基础数据表详解
2.1 物料主数据表结构
t_ICItem表是物料管理的核心,包含以下关键字段:
sql复制CREATE TABLE t_ICItem (
FItemID int PRIMARY KEY, -- 物料内码
FNumber varchar(50), -- 物料编码
FName varchar(100), -- 物料名称
FModel varchar(100), -- 规格型号
FUnitID int, -- 计量单位
FDefaultLoc int, -- 默认仓库
FIsBatchManage bit, -- 批次管理
FIsSNManage bit, -- 序列号管理
FDeleted bit -- 删除标记
)
关联表说明:
- t_ICItemCustom:物料自定义字段
- t_ICItemBase:物料基本属性
- t_ICItemPlan:物料计划属性
2.2 财务凭证相关表
凭证处理涉及的主要表结构:
sql复制-- 凭证头表
SELECT * FROM t_Voucher WHERE FYear=2023 AND FPeriod=7
-- 凭证分录表
SELECT * FROM t_VoucherEntry
WHERE FVoucherID IN (SELECT FVoucherID FROM t_Voucher
WHERE FDate BETWEEN '2023-07-01' AND '2023-07-31')
关键关联表:
- t_Account:会计科目表
- t_Currency:币别表
- t_ExchangeRate:汇率表
3. 常用SQL查询示例
3.1 基础查询模板
sql复制-- 查询库存余额
SELECT a.FItemID, b.FNumber, b.FName, a.FQty
FROM t_ICInventory a
JOIN t_ICItem b ON a.FItemID = b.FItemID
WHERE a.FStockID = 101 -- 仓库ID
-- 查询供应商往来余额
SELECT a.FSupplierID, b.FName, a.FAmount
FROM t_APBalance a
JOIN t_Supplier b ON a.FSupplierID = b.FItemID
WHERE a.FYear = 2023 AND a.FPeriod = 6
3.2 业务分析查询
销售分析查询示例:
sql复制SELECT
c.FNumber AS 客户编码,
c.FName AS 客户名称,
SUM(a.FAmount) AS 销售金额,
COUNT(DISTINCT a.FBillNo) AS 订单数
FROM t_SOOrder a
JOIN t_Customer c ON a.FCustID = c.FItemID
WHERE a.FDate BETWEEN '2023-01-01' AND '2023-06-30'
GROUP BY c.FNumber, c.FName
ORDER BY SUM(a.FAmount) DESC
4. 数据维护与优化实践
4.1 数据清洗SQL示例
sql复制-- 重复物料检查
SELECT FNumber, COUNT(*)
FROM t_ICItem
GROUP BY FNumber
HAVING COUNT(*) > 1
-- 无效单据清理
DELETE FROM t_PORequestEntry
WHERE FInterID NOT IN (SELECT FInterID FROM t_PORequest)
-- 库存负数修正
UPDATE t_ICInventory
SET FQty = 0
WHERE FQty < 0 AND FStockID = 102
4.2 性能优化建议
- 索引优化:
sql复制-- 为常用查询字段创建索引
CREATE INDEX IX_t_Voucher_FDate ON t_Voucher(FDate)
CREATE INDEX IX_t_ICInventory_FItemID ON t_ICInventory(FItemID)
- 查询优化技巧:
- 避免使用SELECT *
- 使用参数化查询防止SQL注入
- 复杂查询拆分为临时表
5. 安全操作规范
- 生产环境操作三原则:
- 必须备份后操作
- 必须限制WHERE条件范围
- 必须使用事务进行测试
sql复制BEGIN TRANSACTION
-- 测试SQL语句
UPDATE t_ICItem SET FName = '测试' WHERE FItemID = 1001
ROLLBACK TRANSACTION
-- 确认无误后改为COMMIT
- 常用系统表查询:
sql复制-- 查询锁表情况
SELECT * FROM sys.dm_tran_locks
WHERE resource_database_id = DB_ID('K3DB')
-- 查询长时间运行会话
SELECT * FROM sys.dm_exec_requests
WHERE status = 'running' AND DB_NAME(database_id) = 'K3DB'
6. 典型问题解决方案
6.1 凭证反过账实现
通过分析数据库操作日志发现,反过账实质是逆向操作:
sql复制-- 1. 查询已过账凭证
SELECT * FROM t_GLVoucher
WHERE FPosted = 1 AND FVoucherID = 12345
-- 2. 反过账操作(需在测试环境验证)
UPDATE t_GLVoucher
SET FPosted = 0, FPosterID = NULL, FPostDate = NULL
WHERE FVoucherID = 12345
-- 3. 删除总账记录
DELETE FROM t_GLBalance
WHERE FVoucherID = 12345
6.2 数据修复案例
科目余额不平修复步骤:
- 先备份相关表
- 查询差异金额:
sql复制SELECT FAccountID, FYear, FPeriod,
FDebit - FCredit AS Balance,
FEndBalance
FROM t_GLBalance
WHERE ABS((FDebit - FCredit) - FEndBalance) > 0.01
- 分析差异原因后修正
7. 高级应用技巧
7.1 跨年度数据查询
sql复制-- 使用UNION ALL合并多年度数据
SELECT FAccountID, FYear, FPeriod, FEndBalance
FROM t_GLBalance
WHERE FAccountID = 5001 AND FYear = 2022
UNION ALL
SELECT FAccountID, FYear, FPeriod, FEndBalance
FROM t_GLBalance
WHERE FAccountID = 5001 AND FYear = 2023
ORDER BY FYear, FPeriod
7.2 存储过程示例
创建月度结账检查存储过程:
sql复制CREATE PROCEDURE sp_GL_MonthEnd_Check
@Year INT,
@Period INT
AS
BEGIN
-- 检查未过账凭证
SELECT COUNT(*) AS UnpostedVouchers
FROM t_Voucher
WHERE FYear = @Year AND FPeriod = @Period AND FPosted = 0
-- 检查损益科目余额
SELECT a.FAccountID, b.FNumber, b.FName, a.FEndBalance
FROM t_GLBalance a
JOIN t_Account b ON a.FAccountID = b.FAccountID
WHERE a.FYear = @Year AND a.FPeriod = @Period
AND b.FAccountType = 5 -- 损益类科目
AND a.FEndBalance <> 0
END
8. 数据接口开发
8.1 外部系统对接方案
- 直接数据库访问(需审批):
python复制import pyodbc
conn = pyodbc.connect('DRIVER={SQL Server};SERVER=K3DBServer;DATABASE=K3DB;UID=readonly;PWD=123456')
cursor = conn.cursor()
cursor.execute("SELECT FItemID, FNumber, FName FROM t_ICItem WHERE FDeleted=0")
for row in cursor:
print(row.FNumber, row.FName)
conn.close()
- 通过K3 API接口(推荐方式):
csharp复制KDWebAPI api = new KDWebAPI("http://k3server/K3API");
var result = api.Invoke("BD_Material", "Query", new {
Filter = "FNumber LIKE '01.%'",
PageSize = 100
});
8.2 数据导出优化
大批量数据导出方案:
sql复制-- 使用BCP工具导出
EXEC xp_cmdshell 'bcp "SELECT * FROM K3DB.dbo.t_ICItem" queryout D:\Export\Items.csv -c -t, -T -S K3DBServer'
-- 使用SSIS包定时导出
-- 配置数据流任务时设置合适的缓冲区大小(默认10MB可调整到50MB)
9. 系统表关系图谱
主要模块表关系说明:
-
财务模块:
- t_Voucher → t_VoucherEntry → t_Account
- t_GLBalance ← t_Account
-
供应链模块:
- t_ICItem → t_ICInventory
- t_POOrder → t_POOrderEntry → t_ICItem
-
生产模块:
- t_MO → t_MOEntry → t_ICItem
- t_BOM → t_BOMChild
经验分享:使用SQL Server Diagram功能可以可视化这些关系,但大型数据库建议只加载部分表避免卡顿
10. 实战案例:库存预警系统
基于K3数据库开发库存预警:
sql复制-- 创建库存预警视图
CREATE VIEW v_InventoryAlert AS
SELECT
i.FItemID,
it.FNumber,
it.FName,
i.FStockID,
s.FName AS StockName,
i.FQty,
ib.FMinStock
FROM t_ICInventory i
JOIN t_ICItem it ON i.FItemID = it.FItemID
JOIN t_Stock s ON i.FStockID = s.FItemID
JOIN t_ICItemBase ib ON i.FItemID = ib.FItemID
WHERE i.FQty < ib.FMinStock AND it.FDeleted = 0
-- 创建邮件预警存储过程
CREATE PROCEDURE sp_SendInventoryAlert
AS
BEGIN
DECLARE @body NVARCHAR(MAX)
SET @body = N'<table border="1"><tr><th>物料编码</th><th>物料名称</th><th>仓库</th><th>当前库存</th><th>安全库存</th></tr>'
SELECT @body = @body +
N'<tr><td>' + FNumber + '</td><td>' + FName + '</td><td>' + StockName +
'</td><td>' + CAST(FQty AS VARCHAR) + '</td><td>' + CAST(FMinStock AS VARCHAR) + '</td></tr>'
FROM v_InventoryAlert
SET @body = @body + N'</table>'
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'K3Alert',
@recipients = 'inventory@company.com',
@subject = '库存预警通知',
@body = @body,
@body_format = 'HTML'
END
11. 数据迁移专项
11.1 新旧系统迁移方案
- 基础资料迁移:
sql复制-- 使用INSERT SELECT语句迁移
INSERT INTO NewK3DB.dbo.t_ICItem(
FItemID, FNumber, FName, FModel, FUnitID)
SELECT
FItemID, FNumber, FName, FModel, FUnitID
FROM OldK3DB.dbo.t_ICItem
WHERE FDeleted = 0
-- 处理自增ID冲突
DBCC CHECKIDENT('t_ICItem', RESEED, 100000)
- 业务数据迁移注意事项:
- 按模块顺序迁移(先基础资料后业务单据)
- 迁移后检查关联完整性
- 使用事务确保一致性
11.2 数据清洗脚本
sql复制-- 处理无效字符
UPDATE t_ICItem
SET FName = REPLACE(REPLACE(FName, CHAR(10), ''), CHAR(13), '')
WHERE FName LIKE '%' + CHAR(10) + '%' OR FName LIKE '%' + CHAR(13) + '%'
-- 标准化日期格式
UPDATE t_Voucher
SET FDate = CONVERT(varchar(10), CONVERT(datetime, FDate, 112), 120)
WHERE ISDATE(FDate) = 1
12. 系统维护SQL集锦
12.1 日常维护脚本
sql复制-- 重建索引
EXEC sp_MSforeachtable 'PRINT ''?''; DBCC DBREINDEX(''?'', '''', 0)'
-- 更新统计信息
EXEC sp_updatestats
-- 检查数据库一致性
DBCC CHECKDB('K3DB') WITH NO_INFOMSGS
12.2 性能监控查询
sql复制-- 查询最耗CPU的SQL
SELECT TOP 10
qs.total_worker_time/qs.execution_count AS avg_cpu_cost,
qs.execution_count,
SUBSTRING(qt.text, (qs.statement_start_offset/2)+1,
((CASE qs.statement_end_offset
WHEN -1 THEN DATALENGTH(qt.text)
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2)+1) AS query_text
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt
ORDER BY avg_cpu_cost DESC
-- 查询缺失索引建议
SELECT
migs.avg_total_user_cost * (migs.avg_user_impact / 100.0) * (migs.user_seeks + migs.user_scans) AS improvement_measure,
mid.statement AS table_name,
mid.equality_columns,
mid.inequality_columns,
mid.included_columns
FROM sys.dm_db_missing_index_group_stats migs
JOIN sys.dm_db_missing_index_groups mig ON migs.group_handle = mig.index_group_handle
JOIN sys.dm_db_missing_index_details mid ON mig.index_handle = mid.index_handle
WHERE mid.database_id = DB_ID('K3DB')
ORDER BY improvement_measure DESC
13. 数据仓库集成方案
13.1 增量抽取设计
sql复制-- 使用时间戳增量抽取
CREATE TABLE dbo.ETL_LastExtract(
TableName varchar(100) PRIMARY KEY,
LastExtractTime datetime
)
-- 凭证增量抽取示例
INSERT INTO DW.dbo.FactVoucher(
VoucherID, Date, Amount)
SELECT
v.FVoucherID, v.FDate, e.FAmount
FROM t_Voucher v
JOIN t_VoucherEntry e ON v.FVoucherID = e.FVoucherID
WHERE v.FDate > (SELECT LastExtractTime FROM ETL_LastExtract
WHERE TableName = 't_Voucher')
-- 更新抽取时间
UPDATE ETL_LastExtract
SET LastExtractTime = GETDATE()
WHERE TableName = 't_Voucher'
13.2 维度表处理技巧
sql复制-- 缓慢变化维处理(Type 2)
INSERT INTO DW.dbo.DimItem(
ItemKey, ItemID, Number, Name,
StartDate, EndDate, CurrentFlag)
SELECT
ROW_NUMBER() OVER(ORDER BY i.FItemID) +
(SELECT MAX(ItemKey) FROM DW.dbo.DimItem),
i.FItemID, i.FNumber, i.FName,
GETDATE(), NULL, 1
FROM t_ICItem i
WHERE NOT EXISTS (
SELECT 1 FROM DW.dbo.DimItem d
WHERE d.ItemID = i.FItemID AND d.CurrentFlag = 1
AND d.Number = i.FNumber AND d.Name = i.FName
)
-- 标记变更记录
UPDATE DW.dbo.DimItem
SET EndDate = GETDATE(), CurrentFlag = 0
WHERE ItemID IN (
SELECT i.FItemID
FROM t_ICItem i
JOIN DW.dbo.DimItem d ON i.FItemID = d.ItemID
WHERE d.CurrentFlag = 1
AND (d.Number <> i.FNumber OR d.Name <> i.FName)
)
AND CurrentFlag = 1
14. 报表开发实战
14.1 财务报表SQL优化
资产负债表查询优化方案:
sql复制-- 原始写法(性能差)
SELECT a.FNumber, a.FName,
(SELECT SUM(FEndBalance)
FROM t_GLBalance b
WHERE b.FAccountID = a.FAccountID
AND b.FYear = 2023 AND b.FPeriod = 6) AS Balance
FROM t_Account a
WHERE a.FAccountType IN (1,2,3,4)
-- 优化写法(使用JOIN)
SELECT a.FNumber, a.FName, SUM(b.FEndBalance) AS Balance
FROM t_Account a
LEFT JOIN t_GLBalance b ON a.FAccountID = b.FAccountID
AND b.FYear = 2023 AND b.FPeriod = 6
WHERE a.FAccountType IN (1,2,3,4)
GROUP BY a.FNumber, a.FName
14.2 自定义报表开发
销售毛利分析报表SQL:
sql复制SELECT
c.FNumber AS 客户编码,
c.FName AS 客户名称,
i.FNumber AS 产品编码,
i.FName AS 产品名称,
SUM(e.FQuantity) AS 销售数量,
SUM(e.FAmount) AS 销售金额,
SUM(e.FCostAmount) AS 成本金额,
SUM(e.FAmount - e.FCostAmount) AS 毛利额,
CASE WHEN SUM(e.FAmount) = 0 THEN 0
ELSE SUM(e.FAmount - e.FCostAmount)/SUM(e.FAmount)
END AS 毛利率
FROM t_SOOrder o
JOIN t_SOOrderEntry e ON o.FInterID = e.FInterID
JOIN t_Customer c ON o.FCustID = c.FItemID
JOIN t_ICItem i ON e.FItemID = i.FItemID
WHERE o.FDate BETWEEN '2023-01-01' AND '2023-06-30'
GROUP BY c.FNumber, c.FName, i.FNumber, i.FName
HAVING SUM(e.FAmount) > 0
ORDER BY SUM(e.FAmount - e.FCostAmount) DESC
15. 系统升级数据准备
15.1 版本兼容性检查
sql复制-- 检查已使用的自定义字段
SELECT * FROM t_TableDescription
WHERE FTableName IN (
SELECT name FROM sys.tables
WHERE name LIKE 't_%'
)
-- 检查已弃用表的使用情况
SELECT DISTINCT OBJECT_NAME(referencing_id) AS UsingObject
FROM sys.sql_expression_dependencies
WHERE referenced_id = OBJECT_ID('t_DeprecatedTable')
15.2 数据转换脚本
sql复制-- 新旧版本字段映射转换
INSERT INTO NewK3DB.dbo.t_NewTable(
FID, FName, FType)
SELECT
FItemID, FName,
CASE FType
WHEN 'A' THEN 1
WHEN 'B' THEN 2
ELSE 0
END
FROM OldK3DB.dbo.t_OldTable
WHERE FDeleted = 0
-- 处理数据结构变更
UPDATE t
SET t.FNewField = o.FOldField
FROM NewK3DB.dbo.t_NewTable t
JOIN OldK3DB.dbo.t_OldTable o ON t.FID = o.FItemID
WHERE t.FNewField IS NULL
16. 异常数据处理
16.1 数据一致性修复
凭证借贷不平修复方案:
sql复制-- 查找不平凭证
SELECT v.FVoucherID, v.FDate, v.FBillNo,
SUM(e.FDebit) AS TotalDebit,
SUM(e.FCredit) AS TotalCredit,
SUM(e.FDebit) - SUM(e.FCredit) AS Diff
FROM t_Voucher v
JOIN t_VoucherEntry e ON v.FVoucherID = e.FVoucherID
GROUP BY v.FVoucherID, v.FDate, v.FBillNo
HAVING ABS(SUM(e.FDebit) - SUM(e.FCredit)) > 0.01
-- 修复方案(需根据实际情况调整)
BEGIN TRANSACTION
-- 1. 备份异常凭证
INSERT INTO t_Voucher_Bak
SELECT * FROM t_Voucher WHERE FVoucherID = 12345
INSERT INTO t_VoucherEntry_Bak
SELECT * FROM t_VoucherEntry WHERE FVoucherID = 12345
-- 2. 调整分录金额(示例)
UPDATE t_VoucherEntry
SET FDebit = FCredit
WHERE FVoucherID = 12345 AND FEntryID = 3
-- 3. 验证
SELECT SUM(FDebit), SUM(FCredit)
FROM t_VoucherEntry
WHERE FVoucherID = 12345
COMMIT TRANSACTION
16.2 并发冲突解决
sql复制-- 检测死锁
SELECT
tl.request_session_id,
wt.blocking_session_id,
tl.resource_type,
tl.resource_database_id,
tl.resource_associated_entity_id,
tl.request_mode,
tl.request_status
FROM sys.dm_tran_locks tl
JOIN sys.dm_os_waiting_tasks wt ON tl.lock_owner_address = wt.resource_address
-- 解决锁表现场
KILL 55 -- 终止阻塞会话
17. 数据安全策略
17.1 敏感数据保护
sql复制-- 加密存储银行账号
CREATE SYMMETRIC KEY K3_Data_Key
WITH ALGORITHM = AES_256
ENCRYPTION BY PASSWORD = 'ComplexP@ssw0rd!'
-- 加密敏感列
OPEN SYMMETRIC KEY K3_Data_Key DECRYPTION BY PASSWORD = 'ComplexP@ssw0rd!'
UPDATE t_Supplier
SET FBankAccountEncrypt = ENCRYPTBYKEY(KEY_GUID('K3_Data_Key'), FBankAccount)
WHERE FBankAccount IS NOT NULL
CLOSE SYMMETRIC KEY K3_Data_Key
17.2 审计日志实现
sql复制-- 创建审计表
CREATE TABLE t_DBAudit(
FLogID int IDENTITY PRIMARY KEY,
FUserID varchar(50),
FOperationTime datetime,
FTableName varchar(100),
FOperationType varchar(20),
FKeyValue varchar(100),
FOriginalData xml,
FNewData xml
)
-- 创建更新触发器
CREATE TRIGGER tr_ICItem_Audit ON t_ICItem
AFTER UPDATE
AS
BEGIN
INSERT INTO t_DBAudit(
FUserID, FOperationTime, FTableName,
FOperationType, FKeyValue,
FOriginalData, FNewData)
SELECT
SUSER_NAME(), GETDATE(), 't_ICItem',
'UPDATE', CAST(i.FItemID AS varchar),
(SELECT * FROM deleted FOR XML PATH('')),
(SELECT * FROM inserted FOR XML PATH(''))
FROM inserted i
END
18. 云端部署适配
18.1 云数据库配置
sql复制-- 弹性查询配置(跨数据库查询)
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'CloudP@ss123';
CREATE DATABASE SCOPED CREDENTIAL K3CloudCred
WITH IDENTITY = 'k3user', SECRET = 'UserP@ss456';
CREATE EXTERNAL DATA SOURCE K3CloudDB
WITH (
TYPE = RDBMS,
LOCATION = 'k3cloud.database.windows.net',
DATABASE_NAME = 'K3CloudDB',
CREDENTIAL = K3CloudCred
);
-- 创建外部表
CREATE EXTERNAL TABLE dbo.ext_ICItem(
FItemID int,
FNumber varchar(50),
FName varchar(100)
)
WITH (
DATA_SOURCE = K3CloudDB,
SCHEMA_NAME = 'dbo',
OBJECT_NAME = 't_ICItem'
);
18.2 混合云数据同步
sql复制-- 使用事务复制实现数据同步
-- 发布服务器配置
EXEC sp_addpublication
@publication = 'K3Replication',
@description = 'K3 cloud data replication',
@sync_method = 'native',
@repl_freq = 'continuous',
@status = 'active';
-- 订阅服务器配置
EXEC sp_addsubscription
@publication = 'K3Replication',
@subscriber = 'cloudserver.database.windows.net',
@destination_db = 'K3CloudDB',
@subscription_type = 'Push';
19. 性能调优实战
19.1 查询计划优化
sql复制-- 强制使用索引提示
SELECT v.FVoucherID, v.FDate, e.FAccountID, e.FAmount
FROM t_Voucher v WITH (INDEX(IX_t_Voucher_FDate))
JOIN t_VoucherEntry e WITH (INDEX(IX_t_VoucherEntry_FVoucherID))
ON v.FVoucherID = e.FVoucherID
WHERE v.FDate BETWEEN '2023-01-01' AND '2023-06-30'
-- 优化统计信息
UPDATE STATISTICS t_ICInventory WITH FULLSCAN
UPDATE STATISTICS t_Voucher WITH FULLSCAN, ROWCOUNT = 10000000
19.2 参数化查询最佳实践
sql复制-- 创建参数化存储过程
CREATE PROCEDURE sp_GetVoucherByDate
@StartDate datetime,
@EndDate datetime
AS
BEGIN
SET NOCOUNT ON;
SELECT v.FVoucherID, v.FBillNo, v.FDate,
e.FExplanation, e.FDebit, e.FCredit
FROM t_Voucher v
JOIN t_VoucherEntry e ON v.FVoucherID = e.FVoucherID
WHERE v.FDate BETWEEN @StartDate AND @EndDate
ORDER BY v.FDate, v.FBillNo
END
-- 应用程序调用示例
EXEC sp_GetVoucherByDate '2023-01-01', '2023-06-30'
20. 扩展开发接口
20.1 Web API封装
csharp复制// ASP.NET Core Web API示例
[ApiController]
[Route("api/k3/[controller]")]
public class ItemController : ControllerBase
{
private readonly string _connStr;
public ItemController(IConfiguration config)
{
_connStr = config.GetConnectionString("K3DB");
}
[HttpGet("{id}")]
public IActionResult GetItem(int id)
{
using var conn = new SqlConnection(_connStr);
var item = conn.QueryFirstOrDefault<ItemDto>(
"SELECT FItemID, FNumber, FName FROM t_ICItem WHERE FItemID = @id",
new { id });
return item == null ? NotFound() : Ok(item);
}
}
public class ItemDto
{
public int FItemID { get; set; }
public string FNumber { get; set; }
public string FName { get; set; }
}
20.2 消息队列集成
sql复制-- 配置Service Broker
ALTER DATABASE K3DB SET ENABLE_BROKER;
-- 创建消息类型和队列
CREATE MESSAGE TYPE [K3DataChanged]
VALIDATION = WELL_FORMED_XML;
CREATE CONTRACT [K3Contract] (
[K3DataChanged] SENT BY INITIATOR
);
CREATE QUEUE [K3DataQueue];
CREATE SERVICE [K3DataService]
ON QUEUE [K3DataQueue] ([K3Contract]);
-- 创建变更通知触发器
CREATE TRIGGER tr_ICItem_Notify ON t_ICItem
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
DECLARE @message xml
SET @message = (
SELECT
CASE
WHEN EXISTS(SELECT 1 FROM inserted) AND
EXISTS(SELECT 1 FROM deleted) THEN 'UPDATE'
WHEN EXISTS(SELECT 1 FROM inserted) THEN 'INSERT'
ELSE 'DELETE'
END AS Operation,
GETDATE() AS ChangeTime,
USER_NAME() AS ChangeUser,
(SELECT * FROM inserted FOR XML PATH('Item')) AS Data
FOR XML PATH('Change')
)
DECLARE @handle uniqueidentifier
BEGIN DIALOG @handle
FROM SERVICE [K3DataService]
TO SERVICE 'K3DataService'
ON CONTRACT [K3Contract]
WITH ENCRYPTION = OFF;
SEND ON CONVERSATION @handle
MESSAGE TYPE [K3DataChanged] (@message);
END CONVERSATION @handle;
END
