Нет, это не имеет ничего общего с кодированием. Это потому, что у вас есть ссылка на сущность í
, которая нигде не определена. Если бы это был HTML, это имя сущности было бы встроено, но это не относится к XML. Помимо нескольких сущностей, таких как amp
и lt
, ссылки на сущности в XML не распознаются, если они не определены в DTD.
О Вашем вопросе:
Я теперь пытаюсь обновить таблицу, которая не имеет большого объема для уникальности, кроме в искусственном первичном ключе. Это означает, что существует риск, что новая запись не может быть уникальной, и я, ненавидят для добавления поля только для принуждения уникальности.
Если Вы используете AutoIncrement для своего первичного ключа, то у Вас есть уникальность, и Вы могли использовать SELECT @@Identity;
получить значение последнего автоматически сгенерированного идентификатора (см. протесты ниже).
Если Вы не используете автоинкремент, и Вы вставляете записи от Доступа, но Вы хотите получить последний от Excel:
удостоверьтесь, что Ваш первичный ключ является поддающимся сортировке, таким образом, можно получить последний с помощью запроса как любой из них:
SELECT MAX(MyPrimaryField) FROM MyTable;
SELECT TOP 1 MyPrimaryField FROM MyTable ORDER BY MyPrimaryField DESC;
или, если сортировка Вашего основного поля не дала бы Вам последнее, необходимо будет добавить, поле DateTime (сказать InsertedDate
) и сохраните текущую дату и время каждый раз, когда Вы создаете новую запись в той таблице, таким образом, Вы могли получить последний как это:
SELECT TOP 1 MyPrimaryField FROM MyTable ORDER BY InsertedDate DESC;
В любом из этих случаев я думаю, что Вы нашли бы добавление первичного ключа AutoIncrement, как являющегося намного легче иметь дело с:
Это не собирается стоить Вам очень
Это собирается гарантировать Вам уникальность Ваших записей, не имея необходимость думать об этом
Это собирается помочь Вам выбрать новую запись, любое использование @@Identity
или посредством сортировки по первичному ключу или получения Max()
.
От Excel
Для получения данных в Excel у Вас есть несколько вариантов:
создайте канал передачи данных с помощью запроса, таким образом, можно использовать результат непосредственно в Ячейке или диапазоне.
запрос от VBA:
Sub GetLastPrimaryKey(PrimaryField as string, Table as string) as variant
Dim con As String
Dim rs As ADODB.Recordset
Dim sql As String
con = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source= ; C:\myDatabase.accdb"
sql = "SELECT MAX([" & PrimaryField & "]) FROM [" & MyTable & "];"
Set rs = New ADODB.Recordset
rs.Open sql, con, adOpenStatic, adLockReadOnly
GetLastPrimaryKey = rs.Fields(0).Value
rs.Close
Set rs = Nothing
End Sub
Отметьте о @@Identity
Необходимо остерегаться протестов при использовании @@Identity
в стандартных базах данных Access (*):
Это только работает с полями AutoIncrement Identity.
Это только доступно, если Вы используете ADO и работаете SELECT @@IDENTITY;
Это возвращает последний используемый счетчик, но это для всех таблиц. Вы не можете использовать его для возврата счетчика для определенной таблицы в Доступе MS (насколько я знаю, если Вы указываете использование таблицы FROM mytable
, это просто проигнорировано).
Короче говоря, возвращенное значение не может быть во всем том, которое Вы ожидаете.
Необходимо запросить его прямо после INSERT
минимизировать риск получения неправильного ответа.
Это означает, что, если Вы вставляете свои данные когда-то и должны получить последний идентификатор в другое время (или другое место), это не будет работать.
Наконец, что не менее важно, переменная установлена только, когда записи вставляются через код программы.
Это означает, что это - запись, был добавлен через пользовательский интерфейс, @@IDENTITY
не будет установлен.
(*): только быть ясным, @@IDENTITY
ведет себя по-другому, и более прогнозирующим способом, если Вы используете режим ANSI 92 SQL для своей базы данных.
Проблема, хотя тот ANSI 92, имеет немного отличающийся синтаксис, чем аромат ANSI 89, поддерживаемый Доступом, и предназначена для увеличения совместимости с SQL Server, когда Доступ используется в качестве фронтэнда.
Попробуйте после макро-кода. Сначала добавьте кнопку к листу от блока управления и вставки после кодов в окне кода
Private Sub CommandButton1_Click()
MsgBox GetLastPrimaryKey
End Sub
Private Function GetLastPrimaryKey() As String
Dim con As String
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim sql As String
con = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\myaccess.mdb;Persist Security Info=False"
sql = "SELECT MAX(id) FROM tblMyTable"
Set cn = New ADODB.Connection
Set rs = New ADODB.Recordset
cn.Open con
rs.Open sql, cn, 3, 3, 1
If rs.RecordCount <> 0 Then
GetLastPrimaryKey = rs.Fields(0).Value
End If
rs.Close
cn.Close
Set rs = Nothing
Set cn = Nothing
End Function
Если искусственный ключ является автонумерацией, можно использовать @@ идентификационные данные.
Обратите внимание, что с обоими этими примерами, транзакция изолируется от других событий, таким образом, возвращенные идентификационные данные являются тем, просто вставленным. Можно протестировать это путем приостановки кода при Отладке. Дб печати. RecordsAffected или Отладка. Распечатайте lngRecs и вставку записи вручную в Table1, продолжите код и обратите внимание, что возвращенные идентификационные данные не являются идентификационными данными записи, вставленной вручную, но предыдущей записи, вставленной кодом.
Пример ДАО
'Reference: Microsoft DAO 3.6 Object Library '
Dim db As DAO.Database
Dim rs As DAO.Recordset
Set db = CurrentDb
db.Execute ("INSERT INTO table1 (field1, Crdate ) " _
& "VALUES ( 46, #" & Format(Date, "yyyy/mm/dd") & "#)")
Debug.Print db.RecordsAffected
Set rs = db.OpenRecordset("SELECT @@identity AS NewID FROM table1")
Debug.Print rs.Fields("NewID")
Пример ADO
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Set cn = CurrentProject.Connection
cn.Execute ("INSERT INTO table1 (field1, Crdate ) " _
& "VALUES ( 46, #" & Format(Date, "yyyy/mm/dd") & "#)"), lngRecs
Debug.Print lngRecs
rs.Open "SELECT @@identity AS NewID FROM table1", cn
Debug.Print rs.Fields("NewID")
Ре: "Я попытался добраться @@ работа ИДЕНТИФИКАЦИОННЫХ ДАННЫХ, но это всегда возвращает 0 использующих кода ниже".
Ваш код отправляет SQL
и SQL2
через различные объекты соединения. Я не думаю @@identity
возвратит что-либо кроме нуля, если Вы не спрашиваете от того же соединения, где Вы выполнили Ваш INSERT
оператор.
Попытайтесь изменить это:
myRecordset.Open SQL2, dbConnectionString, adOpenStatic, adLockReadOnly
кому:
myRecordset.Open SQL2, databaseConnection, adOpenStatic, adLockReadOnly