-1

For this scenario, I have a table like this: ID (Autoincrement, PK), PartType (VarChar), and DesignItemID (VarChar). I would like to combine the columns ID and PartType into column DesignItemID using a single INSERT statement.

Is this possible?

The purpose for this scenario spawns from trying to use an external SQL database for a part library in Altium Designer. Altium Designer needs a unique ID to maintain a proper link to the part that is placed and the DB. Ordinarily, an autoincrement PK could work, however, I need to keep the different types of parts in separate tables (such at resistors in a resistor table and capacitors in a capacitor table, etc.). So, if I have two or more different tables with an autoincrement PK ID column, I will have multiple IDs all starting at 1.

My proposed solution is to make a table with column ID using autoincrement for the PK, column PartType using a char or varchar, and column DesignItemID also using a char or varchar. Upon an INSERT command, I will enter the value RES for resistor or CAP for capacitor for column PartType and somehow LPAD ID to about 6 places and CONCAT with PartType to create DesignItemID RES000001 or CAP000001 for example. Both tables have 1 as PK ID, but, with the part type and padding, a unique column can be made for Altium Designer.

I understand that in a SQL admin interface, I could structure a query to create this unique piece of data, but Altium Designer requires this unique ID to be in a column.

I can accomplish this task in Access by using a calculate field, but Access is limited to number of concurrent users and cannot scale like an external SQL DB can.

Please note that I will have far more columns in the Database that corresponds to the part. I am only focusing on the columns that I do not know if what I am asking can be done.

4

2 回答 2

0

根据您的数据库,

您似乎在要求一个跨越多个表的唯一编号。这最终可以称为 GUID - 如果它在数据库中也应该是唯一的。

这可以用一个 SEQUENCE 来完成。或者您可以查找 GUID 生成器。

使用这样的 GUID 导出多个表是没有问题的 - 您只需从它们所在的任何地方查询并将它们发送到您的输出流。

另一方面,导入更加困难 - 因为您需要知道每个 GUID 所在的位置(在哪个表中)。您可以使用将每个 GUID 映射到它所属的表的另一个表来执行此操作。

于 2021-10-11T18:49:09.897 回答
0

一点点走路而不是说话。您将看到的代码是Oracle,但我猜其他数据库提供相同或相似的选项。请注意,我不了解 Altium Designer。


你问的问题是:

我可以在同一个插入语句中将两个或多个字段合并为一个字段吗?

是的你可以; 您已经知道运算符 - 它是连接。在 Oracle 中,它是concat函数或双管道||运算符。就是这样。

首先,两个样本表(电阻和电容):

SQL> create table resistor
  2    (id_res     varchar2(10) constraint pk_res primary key,
  3     name       varchar2(10) not null
  4    );

Table created.

SQL> create table capacitor
  2    (id_cap     varchar2(10) constraint pk_cap primary key,
  3     name       varchar2(10) not null
  4    );

Table created.

序列将用于创建唯一编号:

SQL> create sequence seqalt;

Sequence created.

数据库触发器,它通过连接一个常量(用于电阻器)和序列号来创建主键值RES,在左边用零填充,长度最多为 7 个字符(因此值长度为 10 个字符):

SQL> create or replace trigger trg_bi_res
  2    before insert on resistor
  3    for each row
  4  begin
  5    :new.id_res := 'RES' || lpad(seqalt.nextval, 7, '0');
  6  end trg_bi_res;
  7  /

Trigger created.

SQL> create or replace trigger trg_bi_cap
  2    before insert on capacitor
  3    for each row
  4  begin
  5    :new.id_cap := 'CAP' || lpad(seqalt.nextval, 7, '0');
  6  end trg_bi_cap;
  7  /

Trigger created.

让我们插入一些行:

SQL> insert into resistor (name) values ('resistor 1');

1 row created.

SQL> select * from resistor;

ID_RES     NAME
---------- ----------
RES0000001 resistor 1

电容器:

SQL> insert into capacitor (name) values ('capac 1');

1 row created.

SQL> insert into capacitor (name) values ('capac 2');

1 row created.

SQL> select * From capacitor;

ID_CAP     NAME
---------- ----------
CAP0000002 capac 1
CAP0000003 capac 2

我的建议是 Altium Designer 使用一个视图而不是一个新表 - 当然,如果可能的话(也许 Designer 需要一个table,除了 table 什么都没有......):

SQL> create or replace view v_altium (designitemid, name) as
  2  select id_res, name from resistor
  3  union all
  4  select id_cap, name from capacitor;

View created.

SQL> /

View created.

SQL> select * from v_altium;

DESIGNITEM NAME
---------- ----------
RES0000001 resistor 1
CAP0000002 capac 1
CAP0000003 capac 2

您现在让 Altium Designer 读取视图,并且 - 从我的角度来看 - 它应该可以正常工作。


如果它必须是一个表(我们称之为它altium),那么它看起来像这样:

SQL> create table altium
  2    (designitemid   varchar2(10) constraint pk_alt primary key,
  3     name           varchar2(10)
  4    );

Table created.

现在将更改触发器,以便它们也可以在表中插入一行altium(参见第 7 行):

SQL> create or replace trigger trg_bi_res
  2    before insert on resistor
  3    for each row
  4  begin
  5    :new.id_res := 'RES' || lpad(seqalt.nextval, 7, '0');
  6    insert into altium (designitemid, name) values (:new.id_res, :new.name);
  7  end trg_bi_res;
  8  /

Trigger created.

SQL> create or replace trigger trg_bi_cap
  2    before insert on capacitor
  3    for each row
  4  begin
  5    :new.id_cap := 'CAP' || lpad(seqalt.nextval, 7, '0');
  6    insert into altium (designitemid, name) values (:new.id_cap, :new.name);
  7  end trg_bi_cap;
  8  /

Trigger created.

让我们尝试一下:

SQL> insert into resistor (name) values ('resistor 4');

1 row created.

SQL> insert into resistor (name) values ('resistor 5');

1 row created.

SQL> insert into capacitor (name) values ('capac 5');

1 row created.

Altium表内容反映resistor和的内容capacitor

SQL> select * from altium;

DESIGNITEM NAME
---------- ----------
RES0000011 resistor 4
RES0000012 resistor 5
CAP0000013 capac 5

SQL>

但是:为什么我更喜欢表格而不是视图?因为一致性可能会受到影响。如果从capacitor表中删除一行怎么办?您还必须从新altium表中删除适当的行,反之亦然。

您不能从altium表中创建外键约束来引用其他表中的主键,因为一旦您尝试将行插入到altium引用的表中resistor,它就会失败,因为 中没有这样的主键capacitor。您可以创建约束,但是 - 这几乎没用:

SQL> drop table altium;

Table dropped.

SQL> create table altium
  2    (designitemid   varchar2(10) constraint pk_alt primary key,
  3     name           varchar2(10),
  4     --
  5     constraint fk_alt_res foreign key (designitemid) references resistor (id_res),
  6     constraint fk_alt_cap foreign key (designitemid) references capacitor (id_cap)
  7    );

Table created.

好的,表已成功创建,但是 - 它会工作吗?

SQL> insert into resistor (name) values ('resistor 7');
insert into resistor (name) values ('resistor 7')
            *
ERROR at line 1:
ORA-02291: integrity constraint (SCOTT.FK_ALT_CAP) violated - parent key not
found
ORA-06512: at "SCOTT.TRG_BI_RES", line 3
ORA-04088: error during execution of trigger 'SCOTT.TRG_BI_RES'


SQL>

不,它不会,因为表中不存在这样的主键capacitor

这意味着您必须手动保持一致性,这总是很棘手。


因此,如果可能,请使用视图。

于 2021-10-11T19:43:31.930 回答