Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如果值存在,则更新_Mysql - Fatal编程技术网

Mysql 如果值存在,则更新

Mysql 如果值存在,则更新,mysql,Mysql,好的,我有一个表,我将收集用户设备。当用户登录时,我希望它注册设备,如果它已经存在,它只想更新时间戳。这仅在用户登录时发生 该表如下所示: device_id => BIGINT AUTOINCREMENT PRIMARY KEY user_id => BIGINT FOREIGN KEY users(id) device_name => VARCHAR(40) (Will be like 'Donald ducks iphone') device_type => VAR

好的,我有一个表,我将收集用户设备。当用户登录时,我希望它注册设备,如果它已经存在,它只想更新时间戳。这仅在用户登录时发生

该表如下所示:

device_id => BIGINT AUTOINCREMENT PRIMARY KEY
user_id => BIGINT FOREIGN KEY users(id)
device_name => VARCHAR(40) (Will be like 'Donald ducks iphone')
device_type => VARCHAR(10) (Will be defined by the client, like "IOS")
last_usage => TIMESTAMP (On update, new timestamp and all that)
因此,当用户登录时,我有用户id、设备名称、设备类型

我想要的是: 如果行中已经存在id、名称和类型,只需更新时间戳,否则插入值

因为这与主键无关,我不知道怎么做。当然,我可以先选择这些值,然后返回这些值,然后再进行更新/插入,但这感觉不对:)

对于Me.Lstbox\u Tables.ItemsSelected中的每个r
'使用所需数据创建记录集
sql=“SELECT*FROM”&Me.Lstbox\u Tables.ItemData(r)
'tablename=“Gahpp00d”+rs!表名称
Set rs=db.OpenRecordset(sql,dbReadOnly)
将SheetName设置为字符串
SheetName=Replace(Me.Lstbox\u Tables.ItemData(r),“GAHPP00D\uU”和“”)
出错时继续下一步
excelWbk.Sheets(SheetName)。选择
如果错误号为0,则
MsgBox错误编号&“:”错误描述(&Err.Description),vbCritical,“错误!!!”
MsgBox“工作表”&SheetName&“不存在”。,vbCritical,“缺少工作表!!!”
excelWbk。关闭False
阿佩克塞尔,退出
出口接头
如果结束
您可以在MySQL 5.0+中使用:

“替换”的工作方式与“插入”完全相同,只是 表与主键或唯一键的新行具有相同的值 索引时,在插入新行之前删除旧行

例如:

REPLACE INTO TableName (user_id, device_id, device_name, device_type, last_usage) VAULES (1, 2, "Test Device Name, "Test Type", NOW()); 

首先,使
设备\u名称
设备\u类型
唯一

现在你有两个选择。您可以使用:

INSERT IGNORE INTO devices (...) VALUES(...)
或者,如果您担心重要错误可能会被忽略,请使用:

INSERT INTO devices (...) VALUES(...)
ON DUPLICATE KEY UPDATE device_id = device_id
请注意,这与
REPLACE
不同,因为这根本不会影响旧记录,而
REPLACE
将创建新的ID和时间戳

编辑:由于现在要更新时间戳,请使用:

INSERT INTO devices (...) VALUES(...)
ON DUPLICATE KEY UPDATE last_usage = NOW()

您可能需要将其转换为mysql作为其mssql,但大致如下:

declare @count int
declare @user varchar
declare @machine varchar
declare @type as varchar

select @count = (select count(*) from [table] where user = @user and machine=@machine and type=@type)

if @count = 0
begin
insert into
[table]
select
@machine,
@user,
@type,
current_timestamp
end

if @count > 0
begin
update
[table]
set timestamp = current_timestamp
where
machine = @machine
and
user = @user
and
type = @type
end
问候,


马库斯

在OP的问题中,哪里说他们想要vb的答案??此外,此答案与问题有什么关系?
INSERT IGNORE
如果值已经存在,则跳过;它不会更新它。请参阅“确定”,但由于设备id是自动递增的(我在插入/更新中不知道该id),因此它还是会创建它。。。主键不能相同,因为它是自动递增的。我应该将这些列设置为其他键类型还是什么?@aam1r是的,我知道,这是需要的行为
REPLACE
将更改ID和时间戳,这是错误的。@gubbfett看不到我的编辑。您应该为
device\u name
device\u type
@guubfett-Yes设置
UNIQUE
约束,但您说您希望它什么都不做(这意味着时间戳应该保持不变)。如果愿意,您可以更新时间戳,我将编辑答案。这将替换旧记录,更改ID和时间戳,而OP希望它不做任何事情。关于您的设置,我要说明的一点是,如果多个用户使用同一设备,您将有多个设备条目。如果这是为库存目的而设计的,我可能会建议也更新用户名。
declare @count int
declare @user varchar
declare @machine varchar
declare @type as varchar

select @count = (select count(*) from [table] where user = @user and machine=@machine and type=@type)

if @count = 0
begin
insert into
[table]
select
@machine,
@user,
@type,
current_timestamp
end

if @count > 0
begin
update
[table]
set timestamp = current_timestamp
where
machine = @machine
and
user = @user
and
type = @type
end