热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

SQLServer由于主外键约束导致插入失败的记录方法

你打算从SQLServer2000数据库的客户表和国别表中导入客户数据到SQLServer2005数据库中。你要确保在导入过程中,客户表中国家代码列的每个值在SQLServer2005数据库中国别表内都有其相应的纪录。你在两个表之间定义一外键,这样,参照完整性将保证

你打算从 SQL Server 2000 数据库的客户表和国别表中导入客户数据到 SQL Server 2005 数据库中。你要确保在导入过程中,客户表中国家代码列的每个值在 SQL Server 2005 数据库中国别表内都有其相应的纪录。你在两个表之间定义一外键,这样,参照完整性将保证

你打算从 SQL Server 2000 数据库的客户表和国别表中导入客户数据到 SQL Server 2005 数据库中。你要确保在导入过程中,客户表中国家代码列的每个值在 SQL Server 2005 数据库中国别表内都有其相应的纪录。你在两个表之间定义一外键,这样,参照完整性将保证若国家代码值在客户表中存在, 而在国别表中不存在时导入程序失败。 你要确保国别表无记录时导入过程不失败。 <无>
--创建Department(deptID,deptName)和UserInfo(userID, userName, sex, loginDate,deptid)
--其中deptID,userID是自动增长的,并且是主键。deptid是外键。并且插入测试数据

--创建序列
CREATE SEQUENCE seq_Dep
 START WITH 1
 INCREMENT BY 1
 NOMAXVALUE
 NOCYCLE
 CACHE 30;
--建表Department
CREATE TABLE Department
(
 deptID VARCHAR2(10) PRIMARY KEY,
 deptName VARCHAR2(20)
);

--插入测试数据
INSERT INTO Department VALUES ('D'||seq_Dep.NEXTVAL,'人事部');
INSERT INTO Department VALUES ('D'||seq_Dep.NEXTVAL,'技术部');
INSERT INTO Department VALUES ('D'||seq_Dep.NEXTVAL,'后勤部');
INSERT INTO Department VALUES ('D'||seq_Dep.NEXTVAL,'经理部');
INSERT INTO Department VALUES ('D'||seq_Dep.NEXTVAL,'销售部');
INSERT INTO Department VALUES ('D'||seq_Dep.NEXTVAL,'服务部');
INSERT INTO Department VALUES ('D'||seq_Dep.NEXTVAL,'公关部');
COMMIT;

--创建序列
CREATE SEQUENCE seq_User
 START WITH 1
 INCREMENT BY 1
 NOMAXVALUE
 NOCYCLE
 CACHE 30;
--建表UserInfo
CREATE TABLE UserInfo
(
 userID VARCHAR2(10) PRIMARY KEY,
 userName VARCHAR2(20),
 sex VARCHAR2(2),
 loginDate DATE,
 deptid VARCHAR2(10) REFERENCES Department (deptID)
);

--插入测试数据
INSERT INTO UserInfo VALUES ('U'||seq_User.NEXTVAL,'Eric Schmidt','男','12-9月-07','D1');
INSERT INTO UserInfo VALUES ('U'||seq_User.NEXTVAL,'Larry Page','男','12-10月-07','D3');
INSERT INTO UserInfo VALUES ('U'||seq_User.NEXTVAL,'Sergey Brin','男','12-11月-07','D5');
INSERT INTO UserInfo VALUES ('U'||seq_User.NEXTVAL,'W. M. Coughran, Jr.','男','1-12月-07','D4');
INSERT INTO UserInfo VALUES ('U'||seq_User.NEXTVAL,'David C. Drummond','女','12-12月-01','D2');
INSERT INTO UserInfo VALUES ('U'||seq_User.NEXTVAL,'Alan Eustace','男','12-9月-07','D1');
INSERT INTO UserInfo VALUES ('U'||seq_User.NEXTVAL,'Jeff Huber','男','12-10月-07','D3');
INSERT INTO UserInfo VALUES ('U'||seq_User.NEXTVAL,'George Reyes','男','12-11月-07','D5');
INSERT INTO UserInfo VALUES ('U'||seq_User.NEXTVAL,'Elliot Schrage','男','1-12月-07','D4');
INSERT INTO UserInfo VALUES ('U'||seq_User.NEXTVAL,'Tim Armstrong','女','12-12月-01','D2');
INSERT INTO UserInfo VALUES ('U'||seq_User.NEXTVAL,'Nikesh Arora','女','12-12月-01','D2');
INSERT INTO UserInfo VALUES ('U'||seq_User.NEXTVAL,'Sukhinder','男','12-9月-07','D1');
INSERT INTO UserInfo VALUES ('U'||seq_User.NEXTVAL,'Vinton G. Cerf','男','12-10月-07','D3');
INSERT INTO UserInfo VALUES ('U'||seq_User.NEXTVAL,'George Reyes','男','12-11月-07','D5');
INSERT INTO UserInfo VALUES ('U'||seq_User.NEXTVAL,'Dave Girouard','男','1-12月-07','D4');
INSERT INTO UserInfo VALUES ('U'||seq_User.NEXTVAL,'Singh Cassidy','女','12-12月-01','D2');
COMMIT;

--3. 在deptid建立索引
CREATE INDEX deptid_index on UserInfo(deptid);

--4. 给Department和UserInfo创建同义词,名称分别是dept, sy_user
CREATE OR REPLACE SYNONYM dept FOR Department;
CREATE OR REPLACE SYNONYM sy_user FOR UserInfo;

/*
5. 通过同义词dept, user来创建视图,
视图要求能查询出“部门名称,部门编号,用户名,性别,注册时间”
*/
CREATE OR REPLACE VIEW view_dept_user
("部门名称","部门编号","用户名","性别","注册时间")
AS SELECT d.deptName,d.deptID,u.userName,u.sex,u.loginDate 
  FROM dept d ,sy_user u  
  WHERE d.deptID=u.deptid;

--14. 使用Instead Of触发器,往第5题创建的视图中插入数据。
SET SERVEROUTPUT ON;
INSERT INTO view_dept_user ('部门名称','部门编号','用户名','性别','注册时间')
  VALUES('仓储部','D6','Dejan Perkovic','男','1-1月-08');

/*
CREATE OR REPLACE VIEW view_dept_user
("部门名称","部门编号","用户名","性别","注册时间")
AS SELECT d.deptName,d.deptID,u.userName,u.sex,u.loginDate 
  FROM dept d ,sy_user u  
  WHERE d.deptID=u.deptid;
*/
CREATE OR REPLACE TRIGGER dept_user_insert
INSTEAD OF INSERT ON view_dept_user
FOR EACH ROW
DECLARE
   CURSOR cur_dept IS SELECT * FROM Department
   WHERE Department.deptID = :NEW.deptID;
   CURSOR cur_user IS SELECT * FROM sy_user
   WHERE sy_user.userName = :NEW.userName;
   d cur_dept%rowtype;
   u cur_user%rowtype;
   did dept.deptID%TYPE;
   uid sy_user.userID%TYPE;
BEGIN
   OPEN cur_dept;
   OPEN cur_user;
   FETCH cur_user INTO u;
   FETCH cur_dept INTO d;   
  /*
   如果插入的数据中部门ID不存在,则将 seq_Dep.NEXTVAL 产生的序号赋值给变量did,执行插入语句新增加一个部门。
   */
   IF cur_dept%NOTFOUND THEN
   did := 'D'||seq_Dep.NEXTVAL;
   INSERT INTO Department(deptID,deptName) VALUES(did,:NEW.deptName);
   /*
   如果插入数据中的员工不存在,则执行插入语句增加一个新员工
   */  
  IF cur_user%NOTFOUND THEN
 uid := 'U'||seq_User.NEXTVAL;
   INSERT INTO UserInfo(userID,userName,sex,loginDate,deptid) VALUES(uid,:NEW.userName,:NEW.sex,:NEW.loginDate,did);
   END IF;
    
  IF cur_dept%FOUND THEN   
  /*
   如果插入的数据中部门ID是已经存在的部门ID,则更新部门名称
   */
   did:=:NEW.deptID;
   UPDATE Department SET Department.deptName WHERE Department.deptID = :NEW.deptID;
   /*
   如果插入数据中的员工不存在,则将seq_User.NEXTVAL 产生的序号赋值给变量uid,执行插入语句增加一个新员工
   */
   IF cur_user%NOTFOUND THEN
   uid := 'U'||seq_User.NEXTVAL;
   INSERT INTO UserInfo VALUES(uid,:NEW.userName,:NEW.sex,:NEW.loginDate,:NEW.deptID);
   ELSE
   /*
   如果插入数据中的员工已存在,则根据部门ID、员工姓名 来更新员工的其他字段的值,员工ID为主键,不用更新。
   考虑到同名员工存在的可能,但员工的ID不可能相同的特点,需要根据插入数据中的部门ID、员工姓名来查询出
   符合要求的员工的ID,用员工ID来进行后续的操作
   */
   SELECT userID INTO uid FROM UserInfo WHERE UserInfo.userName=:NEW.userName AND UserInfo.deptID=did;
   
  UPDATE UserInfo SET UserInfo.sex = :NEW.sex,UserInfo.loginDate = :NEW.loginDate,UserInfo.deptID = :NEW.sex  
  WHERE UserInfo.userID=uid AND UserInfo.userName=:NEW.userName;
   END IF;
   END IF;
   CLOSE ecur;
   CLOSE dcur;
END dept_user_insert;
/
show errors;

出现的错误提示:

警告: 创建的触发器带有编译错误。

SQL> show errors;
TRIGGER DEPT_USER_INSERT 出现错误:

LINE/COL ERROR
-------- -----------------------------------------------------------------
3/31 PLS-00049: 错误的赋值变量 'NEW.DEPTID'
5/30 PLS-00049: 错误的赋值变量 'NEW.USERNAME'
20/56 PLS-00049: 错误的赋值变量 'NEW.DEPTNAME'
26/75 PLS-00049: 错误的赋值变量 'NEW.USERNAME'
26/89 PLS-00049: 错误的赋值变量 'NEW.SEX'
26/98 PLS-00049: 错误的赋值变量 'NEW.LOGINDATE'
33/10 PLS-00049: 错误的赋值变量 'NEW.DEPTID'
34/4 PL/SQL: SQL Statement ignored
34/46 PL/SQL: ORA-00927: 缺少等号
34/72 PLS-00049: 错误的赋值变量 'NEW.DEPTID'
40/37 PLS-00049: 错误的赋值变量 'NEW.USERNAME'

LINE/COL ERROR
-------- -----------------------------------------------------------------
40/51 PLS-00049: 错误的赋值变量 'NEW.SEX'
40/60 PLS-00049: 错误的赋值变量 'NEW.LOGINDATE'
40/75 PLS-00049: 错误的赋值变量 'NEW.DEPTID'
47/66 PLS-00049: 错误的赋值变量 'NEW.USERNAME'
49/40 PLS-00049: 错误的赋值变量 'NEW.SEX'
49/70 PLS-00049: 错误的赋值变量 'NEW.LOGINDATE'
49/103 PLS-00049: 错误的赋值变量 'NEW.SEX'
50/53 PLS-00049: 错误的赋值变量 'NEW.USERNAME'
55/5 PLS-00103: 出现符号 "DEPT_USER_INSERT"在需要下列之一时:
   if

推荐阅读
  • 本文介绍了如何使用 PostgreSQL 的 `UPDATE ... FROM` 语法,通过映射表实现对多行记录进行高效的批量更新。这种方法不仅适用于单列更新,还支持多列的同时更新。 ... [详细]
  • PHP 编程疑难解析与知识点汇总
    本文详细解答了 PHP 编程中的常见问题,并提供了丰富的代码示例和解决方案,帮助开发者更好地理解和应用 PHP 知识。 ... [详细]
  • 构建基于BERT的中文NL2SQL模型:一个简明的基准
    本文探讨了将自然语言转换为SQL语句(NL2SQL)的任务,这是人工智能领域中一项非常实用的研究方向。文章介绍了笔者在公司举办的首届中文NL2SQL挑战赛中的实践,该比赛提供了金融和通用领域的表格数据,并标注了对应的自然语言与SQL语句对,旨在训练准确的NL2SQL模型。 ... [详细]
  • 本文详细介绍了HTML中标签的使用方法和作用。通过具体示例,解释了如何利用标签为网页中的缩写和简称提供完整解释,并探讨了其在提高可读性和搜索引擎优化方面的优势。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ... [详细]
  • 使用C#开发SQL Server存储过程的指南
    本文介绍如何利用C#在SQL Server中创建存储过程,涵盖背景、步骤和应用场景,旨在帮助开发者更好地理解和应用这一技术。 ... [详细]
  • 本文探讨了适用于Spring Boot应用程序的Web版SQL管理工具,这些工具不仅支持H2数据库,还能够处理MySQL和Oracle等主流数据库的表结构修改。 ... [详细]
  • 本文详细介绍了如何通过多种编程语言(如PHP、JSP)实现网站与MySQL数据库的连接,包括创建数据库、表的基本操作,以及数据的读取和写入方法。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • 在使用 DataGridView 时,如果在当前单元格中输入内容但光标未移开,点击保存按钮后,输入的内容可能无法保存。只有当光标离开单元格后,才能成功保存数据。本文将探讨如何通过调用 DataGridView 的内置方法解决此问题。 ... [详细]
  • 本文详细介绍了如何在 Linux 平台上安装和配置 PostgreSQL 数据库。通过访问官方资源并遵循特定的操作步骤,用户可以在不同发行版(如 Ubuntu 和 Red Hat)上顺利完成 PostgreSQL 的安装。 ... [详细]
  • 如何在PostgreSQL中查看数据表
    本文将指导您使用pgAdmin工具连接到PostgreSQL数据库,并展示如何浏览和查找其中的数据表。通过简单的步骤,您可以轻松访问所需的表结构和数据。 ... [详细]
  • 利用存储过程构建年度日历表的详细指南
    本文将介绍如何使用SQL存储过程创建一个完整的年度日历表。通过实例演示,帮助读者掌握存储过程的应用技巧,并提供详细的代码解析和执行步骤。 ... [详细]
  • 本文介绍了如何通过 Maven 依赖引入 SQLiteJDBC 和 HikariCP 包,从而在 Java 应用中高效地连接和操作 SQLite 数据库。文章提供了详细的代码示例,并解释了每个步骤的实现细节。 ... [详细]
author-avatar
手机用户2502900175
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有