我正在创建一个Inventory应用程序,该应用程序使用SQL数据库来跟踪产品。
产品编号的格式为yyyy-xxxx(即8024-1234),其中前4位描述类别,后4位描述递增整数,共同创建产品编号。
创建新产品时,该类别应首先由管理员批准,因此所有新产品都将添加为9999 xxxx。然后,当产品在类别中获得批准时,其产品编号将更改为正确的ProductNumber。
我需要的是在创建新产品时,为最后4位数字生成一个随机数,然后检查它们是否已经存在于数据库中(与前4位数字一起)。因此,在创建新产品时,一些SQL查询应该创建,例如9999-0123,然后仔细检查这个查询是否已经不存在。怎样才能做到这一点?提前感谢!
您没有精确确定正在使用的SGBD,但这里有一个使用Oracle PL/SQL的潜在解决方案:
declare
temp varchar2(10);
any_rows_found number;
row_exist boolean := true;
begin
WHILE row_exist = true
LOOP
temp := '9999-' || ceil(DBMS_RANDOM.value(low => 999, high => 9999));
select count(*) into any_rows_found from my_table where my_column = temp;
if any_rows_found = 1 then
else
row_exist := false;
insert into my_table values (..................., temp);
end if;
end loop;
end;
我们使用DBMS_RANDOM生成随机值,将其连接到9999,然后检查它是否存在,我们循环生成另一个值,如果它不存在,我们插入该值。
关于
如果您想要增量编号,您可以使用序列生成产品编号:
CREATE SEQUENCE product_number
START WITH 1000
INCREMENT BY 1
NOCACHE
NOCYCLE;
每当您插入或更新新产品并需要有效号码时,只需拨打(sequence.nextVal)。然后在产品表中设置(year,product_number)作为主键(或产品号码本身)。如果您不能按所述设置主键,并且想检查序列号是否已经存在,则可以使用生成序列号
SELECT sequence.nextVal FROM DUAL;
然后检查生成编号的产品是否存在。不知道您使用的SQL方言是什么,这是Oracle SQL,但它也可以应用于其他方言。
也不确定目标数据库,但为MS-SQL解决了这个问题。
在第一步中,我不会建议先生成一个随机数,然后检查这个随机数是否存在,并可能一遍又一遍地这样做。
相反,你可以通过并获得当前的最大productnumber,然后从那里开始工作。即使使用varchar,你也会检索最大int-因为你的语法总是-(c=category/p=product)。除此之外,由于目标类别是";9999";。
你可以使用这样的东西:
DECLARE @newID int;
-- REPLACE to remove the hyphen so we are facing an actual integer
-- Cast to be able to calculate with the value i.E. adding 1 on top of it
-- MAX for retrieving the max value
SELECT @newID = MAX(CAST(replace(ProductNumber,'-','') as int)) + 1 from Test
-- Set the ID by default to 99990000 in case there are no values with the 9999-prefix
IF @newID < 99990000
BEGIN
SET @newID = 99990000
END
-- Push back the hyphen into the new ID given you the final new productNumber
-- 5 is the starting index
-- 0 since no chars from the original ID shall be removed
Select STUFF(@newID, 5,0,'-')
因此,如果你目前有一个9999-1423的产品作为你的产品的最高数字;9999-1424";。如果没有前缀为"的产品;9999";你会简单地得到";9999-0000";。
ProductNumber的格式为yyyy-xxxx(即8024-1234),其中前4位描述类别,后4位描述递增整数,共同创建产品编号。
我们将通过一个计算列来实现这一点,该列将类别和产品编号放在各自的字段中。
创建新产品时,该类别应首先由管理员批准,因此所有新产品都将添加为9999 xxxx。然后,当产品在类别中获得批准时,其产品编号将更改为正确的ProductNumber。
简单地说,默认情况下,每个新产品都会自动分配到9999 产品类别
我需要的是在创建新产品时,为最后4位生成一个随机数,然后检查它们是否已经存在于数据库中(与前4位一起)。因此,在创建新产品时,一些SQL查询应该创建,例如9999-0123,然后仔细检查这个查询是否已经不存在。
这可以实现为identity
。这不是随机的,但我认为这不是真正的要求,对吧?
请记住,这些要求中存在许多漏洞。
- 如果您的产品编号从9999-1234更改为8024-1234,但已在报告/文档中显示为9999-1234,则存在问题
- 此格式最多只支持1000种产品。然后你的系统就坏了
- 再说一遍,这个数字真的需要是随机的吗
- 我不会讨论批准和分配的实际机制,一旦这个问题解决了,你需要在另一个问题中问这个问题
ProductNumber
实际上不是一个数字,它是一个代码,所以我不同意这个列名
打开代码。
通过运行以下命令创建表:
CREATE TABLE dbo.Products
(
ProductID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
ProductName VARCHAR(100),
ProductCategoryID INT NOT NULL DEFAULT (9999),
ProductNumber AS (FORMAT(ProductCategoryID,'0000') + '-' + FORMAT(ProductID,'0000'))
)
列的一些解释:
- ProductID将自动生成一个递增的数字,从1开始,每次递增1。它一定是独一无二的。它也被定义为主键
- 如果您没有为ProductCategoryID指定任何内容,它将默认为9999
- ProductNumber是从两列中计算出的特殊值
现在创建一个新产品,看看会发生什么
INSERT INTO dbo.Products(ProductName)
VALUES ('Brown Shoes')
SELECT * FROM dbo.Products
您可以看到产品编号9999-0001
再添加一些,注意产品代码是递增的。这不是随机的。仔细考虑你是否真的需要这是随机的。
现在设置实际产品类别:
UPDATE dbo.Products
SET ProductCategoryID = 7 WHERE ProductID = 1
SELECT * FROM dbo.Products
请注意,产品编号会更新。
需要注意的是,实际产品id实际上只是ProductID
。ProductCode
列只是为了满足您的需求。