怎样删除一个表中的一行数据而不影响另一个相关联的表中的数据?

Doane 2007-10-16 02:29:35
数据库表peij和rk通过peij_no相关联,当我想删除peij表中一行纪录时,不成功,提示报错:
DELETE 语句与 COLUMN REFERENCE 约束 'FK_rk_peij' 冲突。该冲突发生于数据库 'peijian',表 'rk', column 'peij_no'。

No changes made to database.

DELETE FROM peij WHERE peij_no = '000001' AND peij_py = 'jqppqg' AND peij_name = '金枪牌排气管' AND code = 'bdl200' AND brand = '金枪' AND unit = '个' AND in_price = 21.000 AND out_price1 = 25.000 AND outprice2 = 36.000 AND outprice3 = 22.000 AND spec IS NULL AND model IS NULL AND place = '山东济南' AND export IS NULL AND pernum = 21 AND pack IS NULL AND material IS NULL AND roll IS NULL AND jinyong IS NULL AND comment IS NULL

我在“删除”的代码是这样的:
int li_del
li_del = messagebox("提示","确定要删除吗?",Question!,YesNo!,2)
if li_del = 1 then
dw_1.deleterow(dw_1.getrow())
dw_1.update()

else
return
end if

这样肯定是不对的了,要怎么样才能删除表peij中的数据而不影响到rk表?现在的情况是只要这两个表有数据相关联起来就删不掉。我想做的是删除表peij中一行的纪录,而rk表中的与之相关联的纪录依然存在,也就是说peij表中的这个"peij_no"的值已经不存在了,但是rk表中的这个"peij_no"的值还是存在的。实在不行的话,两个表中的纪录都删除也行,只要不报错且可以删除也行的(下下之策)。
不知道我说明白没有,请大家帮帮忙,小弟新手,最好说的明白些,能贴出代码来最好了,谢谢!
...全文
1012 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
SatanAngel 2007-10-18
  • 打赏
  • 举报
回复
查出的数据,如果想删除某一行的话,得到该行数据的主键值,然后用delete语句delete from tbale_name where key = '主键值' ,然后commit。如果想把关联的表里的对应信息也删除,再写个delete语句就可以吧。这些都写在删除按钮事件就可以了,最多再多加一些判断。
我是这样认为的,呵呵,请参考
Doane 2007-10-18
  • 打赏
  • 举报
回复
或者能不能写个存储过程,触发时将进货单的这条纪录和供应商的关联删掉,从而删除供应商保留进货单

不知道能不能只删除这两条纪录之间的关联而不影响其他纪录之间的关联?嘿嘿
Doane 2007-10-18
  • 打赏
  • 举报
回复
大家帮忙解决一下,谢谢了!

反正就是一个目的,删除这个表的纪录,但是与之相关联的另一个表的纪录还在!

或者删除之后将子表中与之相关联的列的数据变成单独存在的也行!
Doane 2007-10-18
  • 打赏
  • 举报
回复
解决了,结帖了,方法是用的9楼的朋友sbks所说的,隐藏了被删除的信息,多谢
Doane 2007-10-17
  • 打赏
  • 举报
回复
楼上的那位大哥说的级联删除是把两个表里的纪录都删除的吧?不是只能删除一个而不影响另一个的?
另外,我觉得你说的那个添加删除标志的方法也许可行,只是怎样才能在供应商显示界面不列出被删除的供应商呢?
能不能举例说明一下呀,我隐隐约约知道你的意思,就是抓不住关键所在,能不能写段代码看看?
多谢了!
sbks 2007-10-17
  • 打赏
  • 举报
回复
对供应商加多一个字段做为删除标志,在供应商显示界面不列出被删除的供应商不就可以了

对于级联删除,在脚本中,把事务对象的autocommit属性设为false,再把那个断开后不提交的设置选上,然后
先删子表,再删主表,全部没有错时才commit,就OK了,整个事务绝对的完整,我都用了N年了:)

例如:
SQLCA.DBMS = "MSS Microsoft SQL Server"
SQLCA.Database = ls_db
SQLCA.LogPass = is_pw
SQLCA.ServerName = is_srv
SQLCA.LogId = "sa"
SQLCA.AutoCommit = False //手动控制提交
SQLCA.DBParm = "CommitOnDisconnect='No'" //断开时rollback,防止事务没完成而中途断线时只提交了其中部分数据

delete from 子表 where id=xxx using sqlca;
if sqlca.sqlcode<>0 then
rollback using sqlca;
return
end if

delete from 主表 where id=xxx using sqlca;
if sqlca.sqlcode<>0 then
rollback using sqlca;
return
end if

commit using sqlca;
Doane 2007-10-17
  • 打赏
  • 举报
回复
netghost说的可能很对,但是太复杂了,我看也看不懂;级联删除是不是把两个表中的纪录都删除了呀?
我只是想删除父表peij中的纪录,而保留子表rk引用的那条纪录
能不能在PB的“删除”控件的clicked事件中通过写代码来实现?或者强制删除?

比如说,进销存中,不在一个供应商那里进货了,然后把这个供应商删除,但是以前的与这个供应商有关的进货单还是要保存下来的,我想要的就是这个效果,怎么解决呢?
jiazishu0327 2007-10-16
  • 打赏
  • 举报
回复
学习
netghost 2007-10-16
  • 打赏
  • 举报
回复
不建议使用级联删除,大概的思路分三步:
1、代码删除外键约束
2、删除数据
3、代码还原外键
我找了我很久前写的一个SQL,我没测试SQL是否有错,也没去整理,仅供参考一下这个处理过程。

--删除具有外键约束的数据
DECLARE @sTable sysname,
@sSQL NVARCHAR(1000),
@sMsg VARCHAR(200),
@sPKColName sysname,
@sPKTable sysname,
@sFKTable sysname,
@sFKColumn sysname,
@sPKColumn sysname,
@sFKName sysname,
@sKeyValue VARCHAR(100), --主键字段值,如单据编号
@iReset bit , -- 1 表示清空整个表 0 不表空表
@iUPDATE_RULE smallint, --0= 对外键的 CASCADE 修改 1= 如果有外键,那么进行 NO ACTION 修改。
@iDELETE_RULE smallint --0= 对外键的 CASCADE 修改 1= 如果有外键,那么进行 NO ACTION 修改

CREATE TABLE #t_fkeys(
PKTABLE_QUALIFIER SYSNAME,
PKTABLE_OWNER SYSNAME,
PKTABLE_NAME SYSNAME,
PKCOLUMN_NAME SYSNAME,
FKTABLE_QUALIFIER sysname,
FKTABLE_OWNER sysname,
FKTABLE_NAME sysname,
FKCOLUMN_NAME sysname,
KEY_SEQ smallint,
UPDATE_RULE smallint,
DELETE_RULE smallint,
FK_NAME sysname,
PK_NAME sysname,
DEFERRABILITY smallint
)
--SELECT * FROM SaleBillVouchS WHERE cSBVCode = 'SI070802001'
--DELETE FROM SaleBillVouchS WHERE cSBVCode = 'SI070802001'
--赋值:表名、需删除的单号
SELECT @sTable = 'SaleBillVouch',@sPKColName = 'cSBVCode',@sKeyValue = 'NO070528110',@iReset = 0

SELECT @sSQL = 'INSERT INTO #t_fkeys EXEC sp_fkeys "' + @sTable + '"'
--PRINT @sSQL
EXECUTE SP_EXECUTESQL @stmt = @sSQL

--1、存在外键约束时先删除外键
IF EXISTS(SELECT TOP 1 * FROM #t_fkeys)
BEGIN
DECLARE cur_fkey CURSOR FOR SELECT FK_NAME,PKTABLE_NAME,FKTABLE_NAME,PKCOLUMN_NAME,FKCOLUMN_NAME FROM #t_fkeys
OPEN cur_fkey
FETCH cur_fkey INTO @sFKName,@sPKTable,@sFKTable,@sPKColumn,@sFKColumn
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @sSQL = 'ALTER TABLE ' + QUOTENAME(@sFKTable) + ' DROP CONSTRAINT ' + @sFKName
EXECUTE SP_EXECUTESQL @stmt = @sSQL
--PRINT @sSQL
IF @@ERROR <> 0
BEGIN
IF @@TranCount > 0 ROLLBACK
SET @sMsg = '删除表[' + @sTable + ']的外键约束[' + @sFKName + ']失败'
RAISERROR(@sMsg, 16, 1)
CLOSE cur_fkey
DEALLOCATE cur_fkey
RETURN
END
FETCH cur_fkey INTO @sFKName,@sPKTable,@sFKTable,@sPKColumn,@sFKColumn
END
CLOSE cur_fkey
DEALLOCATE cur_fkey
END

--2、删除数据
IF @iReset = 1
BEGIN
SELECT @sSQL = 'TRUNCATE TABLE ' + @sTable
EXECUTE SP_EXECUTESQL @stmt = @sSQL
IF @@ERROR <> 0
BEGIN
IF @@TranCount > 0 ROLLBACK
SET @sMsg = '清空表[' + @sTable + ']数据失败'
RAISERROR(@sMsg, 16, 1)
RETURN
END
END
ELSE
BEGIN
SELECT @sSQL = 'ALTER TABLE ' + @sTable + ' DISABLE TRIGGER ALL'
EXECUTE SP_EXECUTESQL @stmt = @sSQL
SELECT @sSQL = 'DELETE FROM ' + @sTable + ' WHERE ' + @sPKColName + ' = "' + @sKeyValue + '"'
EXECUTE SP_EXECUTESQL @stmt = @sSQL
IF @@ERROR <> 0
BEGIN
IF @@TranCount > 0 ROLLBACK
SELECT @sSQL = 'ALTER TABLE ' + @sTable + ' ENABLE TRIGGER ALL'
EXECUTE SP_EXECUTESQL @stmt = @sSQL
SET @sMsg = '删除表[' + @sTable + ']数据失败:' + @sSQL
RAISERROR(@sMsg, 16, 1)
RETURN
END
SELECT @sSQL = 'ALTER TABLE ' + @sTable + ' ENABLE TRIGGER ALL'
EXECUTE SP_EXECUTESQL @stmt = @sSQL
END

--3、还原外键
IF EXISTS(SELECT TOP 1 * FROM #t_fkeys)
BEGIN
DECLARE cur_fkey CURSOR FOR SELECT FK_NAME,PKTABLE_NAME,FKTABLE_NAME,PKCOLUMN_NAME,FKCOLUMN_NAME,UPDATE_RULE,DELETE_RULE FROM #t_fkeys
OPEN cur_fkey
FETCH cur_fkey INTO @sFKName,@sPKTable,@sFKTable,@sPKColumn,@sFKColumn,@iUPDATE_RULE,@iDELETE_RULE
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @sSQL = 'ALTER TABLE ' + QUOTENAME(@sFKTable) + ' ADD CONSTRAINT ' + QUOTENAME(@sFKName) + ' FOREIGN KEY ( ' +
QUOTENAME(@sFKColumn) + ' ) REFERENCES ' + QUOTENAME(@sPKTable) + ' ( ' +

QUOTENAME(@sPKColumn) + ' ) ' + CASE WHEN @iDELETE_RULE = 0 THEN ' ON DELETE CASCADE ' ELSE '' END +
CASE WHEN @iUPDATE_RULE = 0 THEN ' ON UPDATE CASCADE ' ELSE '' END
--PRINT @sSQL
EXECUTE SP_EXECUTESQL @stmt = @sSQL
IF @@ERROR <> 0
BEGIN
IF @@TranCount > 0 ROLLBACK
SET @sMsg = '还原表[' + @sTable + ']的外键约束[' + @sFKName + ']失败:' + @sSQL
RAISERROR(@sMsg, 16, 1)
CLOSE cur_fkey
DEALLOCATE cur_fkey
RETURN
END
FETCH cur_fkey INTO @sFKName,@sPKTable,@sFKTable,@sPKColumn,@sFKColumn,@iUPDATE_RULE,@iDELETE_RULE
END
CLOSE cur_fkey
DEALLOCATE cur_fkey
END

DROP TABLE #t_fkeys

SELECT @sSQL = 'EXEC sp_fkeys "' + @sTable + '"'
EXECUTE SP_EXECUTESQL @stmt = @sSQL
zhangwenqian 2007-10-16
  • 打赏
  • 举报
回复
sqlserver2000里面有设置的.
关联删除选项打勾就行了.
Doane 2007-10-16
  • 打赏
  • 举报
回复
我用的是sqlsever2000,你们说的我不是很明白,能不能说的清楚点,具体应该怎么做呢?谢谢!
是不是用代码先把关联删除,然后再删除数据,这样的话删除完了关联还有吗?代码是怎样的啊?
我下班了,明天早上来,辛苦哥哥们了
jlwei888 2007-10-16
  • 打赏
  • 举报
回复
相关联的表是有删除次序的!
如果删除的是子表的数据是没有问题的!
如果删除的是父表的数据,首先数据库要看子表是否引了这条数据,如果使用了就不能删除了!
这就是关联表的作用,保证数据的有效性!

解决办法:
1.你先删除子表!再删父表!
2。把关联删除!那就以随便删了!
SatanAngel 2007-10-16
  • 打赏
  • 举报
回复
把数据窗口的update属性中的:Where Clause for Update/Delete改成Key Columns试试
zhangwenqian 2007-10-16
  • 打赏
  • 举报
回复
你是什么数据库?
可以在数据库中设置关联删除的,
你可以试一下.
数据可视化有什么意义?】 举一个身边的例子,我们平时在电视上看到的天气预报,会用不同的色块代表不同地区的气温、降水情况。通过观察区域色块分布,我们可以马上了解哪里气温高,哪里雨水多。 这种数形结合的形式,让我们更容易抓住重点信息,比枯燥的文字、简单表格更有吸引力。 数据可视化,就是让数据分析的结果以最直观的方式呈现,将“孤独”的数据联系起来,让“单调”的数据生动起来。通过观察可视化图表,数据之间的关联、变化一目了然。 【“无处不在”的数据分析与可视化】 一图胜千言,数据分析与可视化如今在我们的工作和生活中处处可见,职场中90%以上的岗位都会跟数据打交道。掌握数据分析与可视化技能,可以极大提升工作效率。 【4.5小时极速提升数据能力数据小白也能轻松上手】 Python数据分析与可视化的学习,重在实操,空谈语法毫无意义。 本课程着重讲解数据分析与可视化工具的实操应用,结合实战案例,带你边学边练,重点知识充分理解。 四大案例结合实际场景,帮助你加深记忆,并且在日后的求职面试或毕业设计中,这些案例都可以复用。 【通解数据科学 拓宽收益渠道】 如今,许多行业都有数据方向的人才需求。 掌握数据分析与可视化技能,你就可以: 【适用人群】 【三重权益】

1,078

社区成员

发帖
与我相关
我的任务
社区描述
PowerBuilder 相关问题讨论
社区管理员
  • 基础类社区
  • WorldMobile
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧