我正在创建一个将文档保存到 SharePoint 的程序,当我点击它时会保存文档:
name,
date,
username,
location
version
到SQL。现在这是我的问题。每个新文档版本需要增加/添加1。 所以假设我们有版本-1,点击时必须是版本-2 我不能使用自动增量,因为可能有不同的文档 具有不同的名称,需要根据正确的文档名称添加版本。
现在被警告我很累,因为地狱和我的SQL过程并不漂亮:
@username varchar(100),
@Type varchar(100),
@Name varchar(100),
@Version int,
@Location varchar(100)
AS
SET @VERSION = 1
INSERT INTO TABLE (Username,[Date],[Type],Name,[Version],Location)
VALUES('Wolf',GetDate(),'pdf','doc',@version ,@Location)
SELECT max([Version]) FROM table
这大致就是它现在的样子我只需要在每次插入一个新文档时能够为版本添加1,并且为了参数起见它可以说是一个手册。
对于橡树编辑,请注意我没有在48小时内睡觉我累了,拼写是我最不担心的事情答案 0 :(得分:4)
您的代码存在的问题是您始终在插入之前将版本号设置为1:
SET @VERSION = 1
您需要将表之前中的当前最高版本添加到插入内容中。试试这个:
Declare @username varchar(100) = 'Wolf',
@Type varchar(100) = 'pdf',
@Name varchar(100) = 'doc',
@Version int,
@Location varchar(100) = 'TestLoc'
Select @Version = IsNull(Max([Version]), 0) + 1
From Test
Where Name = @Name
INSERT INTO Test (Username,[Date],[Type],Name,[Version],Location)
VALUES(@username,GetDate(),@type,@name,@version ,@Location)
Select Max([Version]) From Test
Where Name = @Name
您可以在SqlFiddle
上看到这一点答案 1 :(得分:4)
@username varchar(100),
@Type varchar(100),
@Name varchar(100),
@Version int,
@Location varchar(100)
as
IF NOT EXISTS(select * from table where type = 'USERGUIDE')
BEGIN
SET @VERSION = 1
END ELSE BEGIN
SET @VERSION = (SELECT MAX(VERSION) + 1 FROM table WHERE TYPE = 'USERGUIDE')
END
SELECT @VERSION [VERSION]
答案 2 :(得分:3)
以下是使用触发器的示例。
正如我在评论中指出的那样,我不建议明确地插入version
,而是让列默认为值1,如果插入了具有已存在行的名称和类型的新行,触发器搜索此项目的最高版本并更新插入的行。
请注意,这是T-SQL
(SQL-Server,因为您没有指定DBMS;))
虽然我非常确定只有OUTER APPLY
- 关键字和TOP
是特定于T-SQL的。
我没有完全把它上传到sqlfiddle,所以我在这里包含了表定义和示例插入,因此您可以轻松地重现:
CREATE TABLE Documents (ID INT IDENTITY(1,1), name NVARCHAR(127), type NVARCHAR(10), date DATETIME, username NVARCHAR(127), location NVARCHAR(127), version INT DEFAULT 1);
GO
CREATE TRIGGER VersionUpdater
ON Documents
AFTER INSERT, UPDATE
AS
UPDATE Documents
SET Documents.version = Documents.Version + ISNULL(LastVersion.version, 0)
FROM Documents
INNER JOIN inserted ON Documents.ID = inserted.ID
OUTER APPLY
(
SELECT TOP 1
version
FROM Documents AS ExistingDocuments
WHERE
ExistingDocuments.name = inserted.name
AND ExistingDocuments.type = inserted.type
AND ExistingDocuments.ID != inserted.ID
ORDER BY version DESC
) AS LastVersion
GO
INSERT INTO Documents (name, type, date, username, location)
SELECT 'master yodas wisdoms', 'pdf', GETUTCDATE(), 'luke skywalker', 'Tatooine'
INSERT INTO Documents (name, type, date, username, location)
SELECT 'master yodas wisdoms', 'pdf', GETUTCDATE(), 'luke skywalker', 'Tatooine'
INSERT INTO Documents (name, type, date, username, location)
SELECT 'master yodas wisdoms', 'pdf', GETUTCDATE(), 'luke skywalker', 'Tatooine'
如果你然后SELECT * FROM Documents
,你会看到三个条目都有不同的版本。
PS:对于那些想知道的人:UNIONING三个插入将无法获得所需的结果,但这也不是一个可行的用例,因为你一次插入同一文档的3个版本。
PPS:我知道yoda不是来自Tatooine,它只是样本数据,但随意纠正我;)答案 3 :(得分:3)
我真的不知道vb.net AT ALL,但是我将允许自己总结一下这里被问到的内容并尝试在PLAIN SQL中回答(我在oracle,firebird和mysql上):
TABLE
的表格,其中包含docs,其中一列是VERSION
VERSION
递增 LI>
NAME
创建多条记录,区别仅为VERSION
并插入日期。如果这一切都是真的,那么就应该这样做:
NAME
VERSION
,如果不是VERSION
并正常插入,这导致以下查询,这在ORACLE中工作,可能有点混乱,因为查询比上面的顺序有点倒退:
insert into TABLE (Username, Date, Type, Name, Version, Location)
VALUES('Wolf', CURRENT_DATE, 'pdf', 'doc',
(select nvl(max(Version)+1, 1) from TABLE where Name = 'pdf'),
'Location');
注意第三行中的SELECT
- 您应该将相同的变量绑定到此子查询中的Name,就像在INSERT
语句中的第二行一样。话虽如此,子查询
select nvl(<something>+1 , 1) from TABLE;
如果<something>
评估为{{1},将1
增加1 ,或数字<something>
如果NULL
中尚不存在给定的Name
,它将会出现。在这种情况下,我们的TABLE
将从同一个表中<something>
递增1(顺便说一句,您需要MAX(VERSION)
上的索引)。请注意,Name
仍为NULL+1
,因此我们需要使用NVL。
这是在Oracle 上执行此操作的中等简单,漂亮的方法。
在MySQL 上,您无法从一个语句(AFAIK)中插入同一个表中的任何内容,因此这将分为两个步骤。首先,我们将选择NULL
或数字MAX(VERSION)+1
,然后我们将正常插入。我们可以使用一个过程来包装它,或者只使用两个语句(再次,纯SQL,我测试过它):
1
立即
select COALESCE(MAX(VERSION)+1, 1) from TABLE where Name = 'pdf' into @incver;
请注意,第一个查询的行为有点像INSERT查询,这意味着它会静默地将值放入变量insert into TABLE (Username, Date, Type, Name, Version, Location)
VALUES ('Wolf', now(), 'pdf', 'doc', @incver, 'Location');
,并说它影响了1行。不会显示任何结果。然后在第二个语句中使用变量@incver
。此外,MySQL上的@incver
与COALESCE
在ORACLE上执行的操作大致相同,NVL
成为名为CURRENT_DATE
的函数。
最后, Firebird ....这与ORACLE相同!除CURRENT_DATE外,现在将是CURRENT_TIMESTAMP或CURRENT_DATE和CURRENT_TIME的某些串联。
我希望你能从所有这些中推断出一些有用的东西,可以集成到你的vb.net
中答案 4 :(得分:2)
试试吧......
@username varchar(100),
@Type varchar(100),
@Name varchar(100),
@Version int,
@Location varchar(100)
as
IF EXISTS(SELECT Version FROM table WHERE Type=@Type AND Name = @Name)
BEGIN
SET @Version = (SELECT TOP(1) Version FROM table
WHERE Type=@Type
AND Name = @Name
ORDER BY Version DESC);
SET @Version = @Version+1;
END
ELSE
SET @VERSION = 1;
Insert into table .......
答案 5 :(得分:2)
您的代码应该在您在不同的环境中使用时工作。
@username varchar(100),
@Type varchar(100),
@Name varchar(100),
@Version int,
@Location varchar(100)
AS
SET @VERSION = 1
INSERT INTO TABLE (Username,[Date],[Type],Name,[Version],Location)
VALUES('Wolf',GetDate(),'pdf','doc',@version ,@Location)
SELECT max([Version]) FROM table
答案 6 :(得分:1)
让它变得非常简单。只需创建一个标量函数并将其设置为默认值。例如
CREATE FUNCTION fn_getMaxValue()
RETURNS int
AS
BEGIN
DECLARE @return int;
SELECT @return = (max(Version) +1) From Table_1
if (@return is null)
set @return =1;
RETURN @return;
END
答案 7 :(得分:1)
按类型和名称搜索,因为具有名称和类型的文档是您要在其上增加版本的条件。
@username varchar(100), @Type varchar(100), @Name varchar(100), @Version int, @Location varchar(100)
选择@Version = IsNull(Max([Version]),0)+ 1 从表 其中[类型] = @Type&amp;&amp;名称= @Name
INSERT INTO表(用户名,[日期],[类型],名称,[版本],位置) VALUES(@用户名,GETDATE(),@类型,@名称,@版,@位置)