powered by simpleCommunicator - 2.0.41     © 2025 Programmizd 02
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / FAQ. Что мы знаем про каунтеры (aka счетчики)
25 сообщений из 176, страница 6 из 8
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32430282
Фотография Владимир Саныч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Для полноты картины:

create table xx (id counter)

Эта команда создает таблицу со счетчиком. Странно, что до сих пор в этом топике она не появилась.
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32484405
Фотография Владимир Саныч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Получение последнего значения счетчика для adp:

SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]

Спасибо Темному!
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32484494
Фотография Темный
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вах! Прыятно, да!
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32487058
Фотография Артист
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
маленькое уточнение
SELECT @блабла = SCOPE_IDENTITY
в ХП вернет null
пользоваться параметром вывода
RETURN SCOPE_IDENTITY
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32487060
Odess
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Странно, у меня "SELECT SCOPE_IDENTITY() as maxID" возвращает не NULL - а реальное значение счетчика. A2002, SQL 2000.
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32487061
Фотография Артист
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
у меня null
ado.net + msde
щас в bol залезу
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32487063
Фотография Владимир Саныч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Мужики, вы говорите о разных командах.
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32487064
Odess
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня выдавал NULL когда я добавлял запись через .ADDNEW, пришлось переделать через "insert into ..." - тогда все заработало. Почему не работает в первом случае - лень было разбираться...
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32487065
Odess
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 ВС
Мы говорим об SCOPE_IDENTITY() - а как ее возвращать дело второе ИМХО.
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32487067
Фотография Владимир Саныч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Вы говорите о том, что через
SELECT SCOPE_IDENTITY() as maxID
и
RETURN SCOPE_IDENTITY
оно работает, а через
SELECT @блабла = SCOPE_IDENTITY
нет. Вы тут спорите о чем-то, а спорить не о чем.
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32487071
Фотография Артист
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BOL дома нету,\r
прошолся гуглом и нашел тока на клиппере кто то столкнулся тынц \r
и Павла 2001 года тынц но у меня не то, я через command, завтра на ado.net форуме задам\r
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
ALTER PROCEDURE dbo.spNewSD2\r
\r
....\r
\r
AS\r
        INSERT INTO tSdelka ( dogovor, ddogovor,  ....)\r
        VALUES (@ndogovor, @ddogovor,  ...)\r
\r
SELECT @idsd = SCOPE_IDENTITY()\r
...\r
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32487073
Фотография Артист
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
тьфу, прошу прошения...
подмахнуф вместо @@identity незаметил :)
все ухожу спать, спасибо!
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32487074
Odess
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Артист
Кларион и Клиппер абсолютно разные вещи ;-)
Я аж прыгул по ссылке - думаю неуж то Клиппер с эскюлем стыковали? ;-)))
Я на Клиппере много задач решил в свое времяю Он даже лицензионный был у меня...
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32487075
Фотография Артист
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вернулся из кровати
позвольте а кроме как в параметре я тогда несмог бы использовать SCOPE_IDENTITY ?

Кларион и Клиппер абсолютно разные вещи ;-)
ну да кларион магнитолы есть такие
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32487081
Фотография Артист
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сам же и отвечаю, после INSERT писать SCOPE_IDENTITY в переменную\r
и юзать - иначе SCOPE_IDENTITY будет null\r
/topic/87320\r
опять с вашими идентитями не выспалюсь ...
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32504869
Фотография Владимир Саныч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Самый-самый последний вариант.

Вопросы.

Q1: Как создать свой счетчик (чтобы поле было не типа счетчик)?

Q2: Как заставить счетчик начать выдавать значения начиная с некоторой заданной величины?

Q3: Может ли поле счетчика содержать повторяющиеся значения?

Q4: В таблице есть счетчик, но его значения идут не подряд, несколько чисел в середине отсутствуют. Как перезаполнить поле, чтобы дырок не было? (Другой вариант вопроса. Счетчик показывает, что последняя запись в моей таблице имеет номер N, а реально записей меньше. Почему счетчик неправильно считает количество записей в таблице? Что это - баг или фича?)

Q5: Как сымитировать счетчик в отчете?

Q6: Как сымитировать счетчик в запросе на добавление?

Q7: Как сымитировать счетчик в обычном запросе либо ленточной форме?

Q8: Как получить значение счетчика только что добавленной записи?

Q9: Как создать одним запросом таблицу со счетчиком?

Вопросы с ответами.

Q1: Как создать свой счетчик (чтобы поле было не типа счетчик)?

A: Надо написать функцию, к которой обращаться либо в DefaultValue контрола (к сожалению, DefaultValue поля в таблице допускает только ограниченный набор стандартных функций), либо в программе, которая добавляет запись через рекордсет, либо в запросе на добавление. Ниже приведено несколько вариантов такой функции. Особое внимание надо уделить обработчику ошибок.

Вариант 1:

Код: plaintext
Nz(DMax(...), 0 )+ 1 

Так можно нумеровать записи даже внутри группы, а не только насквозь через всю таблицу. Для этого надо правильно задать параметры DMax.

Правда, надо отдельно позаботиться о ситуации, когда два юзера обратятся к этому "генератору счетчиков" одновременно. На этот случай надо написать обработчик ошибок.

Вариант 2: Заводим отдельную таблицу с одним полем типа счетчик и без данных. Приводимая ниже процедура обращается к такой таблице и возвращает очередное значение для "нашего" счетчика. Внимание - файл, в котором сидит эта таблица, запрещено сжимать.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
Function Cou() As Long

Dim ws As Workspace, db As Database
Dim rsCounter As Recordset

On Error GoTo errCou
Set ws = DBEngine( 0 )
Set db = CurrentDb
 1 
ws.BeginTrans
 2 
Set rsCounter = db.OpenRecordset("select * from tabCounter")
 3 
rsCounter.AddNew
Cou = rsCounter!nCounter
'Close without update!'
rsCounter.Close
 4 
ws.CommitTrans
 5 
Exit Function

errCou:
Select Case Erl
    Case  3 
        rsCounter.Close
        Set rsCounter = Nothing
        ws.Rollback
        DBEngine.Idle DB_FREELOCKS
        Resume  1 
    Case  2 ,  4 
        ws.Rollback
        DBEngine.Idle DB_FREELOCKS
        Resume  1 
    Case Else
        Resume Next
End Select

End Function 

Подвариант: все-таки делать rsCounter.Update, тогда по виду этой таблицы будет сразу ясно, какое значение было выдано последним. Правда, в этом случае файл станет расти.

Еще подвариант: держать в этой таблице одну запись, в которой находится очередное значение счетчика, и вместо AddNew делать Edit и rsCounter!nCounter=rsCounter!nCounter+1, а потом соответственно Update.

Вариант 3 (от Гетца): Держим в отдельной таблице очередное значение счетчика и каждый раз увеличиваем его на 1. Таблица блокируется на момент чтения и увеличения счетчика, а все, кто в нее будут в это время стучаться, спокойно ждут (см. обработчик ошибок adhGetNextAutoNumber_Err) освобождения таблицы.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
Function adhGetNextAutoNumber(ByVal strTableName As String) As Long

    On Error GoTo adhGetNextAutoNumber_Err

    Dim wrk As dao.Workspace
    Dim db As dao.Database
    Dim rstAutoNum As dao.Recordset
    Dim lngW As Long
    Dim lngX As Long
    Dim intRetryCount As Integer
    
    Randomize
    DoCmd.Hourglass True
    intRetryCount =  0 

    Set wrk = dao.DBEngine.Workspaces( 0 )
    Set db = wrk.OpenDatabase(adhCurrentDBPath() & adhcAutoNumDb, False)
    Set rstAutoNum = db.OpenRecordset(strTableName & "_ID", dbOpenTable, dbDenyRead)

    rstAutoNum.MoveFirst
    rstAutoNum.Edit
    rstAutoNum!NextAutoNumber = rstAutoNum!NextAutoNumber +  1 
    rstAutoNum.Update
 
    adhGetNextAutoNumber = lngNextAutoNum

adhGetNextAutoNumber_Exit:
    DoCmd.Hourglass False
    On Error Resume Next
    rstAutoNum.Close
    Set rstAutoNum = Nothing
    db.Close
    Set db = Nothing
    wrk.Close
    Set wrk = Nothing
    Exit Function

adhGetNextAutoNumber_Err:
    Select Case Err.Number
        Case adhcErrRI, adhcLockErrCantUpdate2, adhcLockErrTableInUse
            intRetryCount = intRetryCount +  1 
            If intRetryCount > adhcLockRetries Then
                adhGetNextAutoNumber = - 1 
                Resume adhGetNextAutoNumber_Exit
            Else
                dao.DBEngine.Idle
                lngW = intRetryCount ^  2  * _
                  Int((adhcLockUBound - adhcLockLBound +  1 ) * Rnd() + adhcLockLBound)
                For lngW =  1  To lngW
                    DoEvents
                Next lngW
                Resume
            End If
        Case Else
            MsgBox "Error " & Err.Number & ": " & Err.Description, _
             vbOKOnly + vbCritical, "adhGetNextAutoNumber"
            adhGetNextAutoNumber = - 1 
            Resume adhGetNextAutoNumber_Exit
    End Select

End Function

Q2: Как заставить счетчик начать выдавать значения начиная с некоторой заданной величины?

A1: Добавить в таблицу со счетчиком при помощи инсерта запись, в которой полю счетчика дается значение на 1 меньше, чем надо. Потом удалить эту запись. Способ работает только при условии, что этот счетчик этого или большего значения еще не выдавал. (Если таким образом дать счетчику отрицательное значение, то он начнет выдавать отрицательные значения, несмотря на то что уже выдавал значения, большие их. Играя на этом, можно добиться, чтобы счетчик выдавал любые значения, в т.ч. и те, которые уже были.)

A2: Сжать базу, в которой сидит таблица со счетчиком. Счетчик будет выдавать значения начиная с наибольшего из существующих +1. В некоторых версиях Аксесса это работает только при условии, что таблица со счетчиком пуста (и тогда счетчик начнет выдавать значения с 1).

A3: Начиная с Аксесса 2000, можно запустить запрос наподобие такого:

Код: plaintext
alter table Таблица1 alter column ПолеСчетчик counter( 1 , 1 )

Q3: Может ли поле счетчика содержать повторяющиеся значения?

A: В принципе да. Этого несложно достичь, меняя состояние счетчика описанными способами. Однако если при этом возникнут нарушения ключа (вообще говоря, поле счетчика можно и не делать ключевым, но обычно все-таки принято делать), то записи просто не смогут добавляться. Каждая неудачная попытка добавить запись будет увеличивать значение счетчика на 1. Когда зона существующих значений будет пройдена, то записи опять смогут добавляться.

Q4: В таблице есть счетчик, но его значения идут не подряд, несколько чисел в середине отсутствуют. Как перезаполнить поле, чтобы дырок не было? (Другой вариант вопроса. Счетчик показывает, что последняя запись в моей таблице имеет номер N, а реально записей меньше. Почему счетчик неправильно считает количество записей в таблице? Что это - баг или фича?)

A: Это нормальная ситуация. Если возникла необходимость, чтобы значения счетчика шли подряд, значит база была спроектирована неверно. Поле счетчика должно служить только для однозначной идентификации записей (и, возможно, порядка их занесения), юзер не должен видеть его значений, а если и увидит, то не должен возражать против тех значений, которые есть. Счетчик не служит для подсчета записей.

Q5: Как сымитировать счетчик в отчете?

A: Заводим текстбокс и задаем ему свойства:

Код: plaintext
1.
ControlSource = "= 1 "
RunningSum = True

Q6: Как сымитировать счетчик в запросе на добавление?

A: Пишем функцию примерно такого вида:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Function MyFun(varDummy As Variant, Optional iStartValue As Variant) As Long
Static n As Long
If IsMissing(iStartValue) Then
    MyFun = n
    n = n +  1 
Else
    n = iStartValue
    MyFun = True
End If
End Function

В запросе обращаемся к ней дважды:

в части WHERE - с параметрами (чтоугодно,N), где N равно нужному начальному значению счетчика;

в части SELECT - в качестве первого параметра передавать любое поле из таблицы, второй параметр не указывать.

Внимание: упрощать этот код, удаляя из него параметр, передаваемый в части SELECT, - нельзя. Без параметра функция будет вызвана только один раз, а не в каждой записи заново.

Q7: Как сымитировать счетчик в обычном запросе либо ленточной форме?

A1:
SELECT (Select Sum(1) From t AS p Where p.f<=p1.f), p1.f
FROM t AS p1
ORDER BY p1.f;

A2:
SELECT DCount("f", "t","f<=" & CStr(f)), f
FROM t
ORDER BY f;

Примечание 1. Поле f обязано быть уникальным.

Примечание 2. Способ 1 быстрее работает, но является необновляемым.

Q8: Как получить значение счетчика только что добавленной записи?

A1: Если запись добавляется через рекордсет, то так:

Код: plaintext
1.
2.
3.
rs.AddNew
переменная = rs!полесчетчика
...
rs.Update

A2: Более широкий круг применимости у такого способа:

Код: plaintext
1.
2.
3.
4.
5.
Dim rs As ADODB.Recordset 
Set rs = New ADODB.Recordset
CurrentProject.Connection.Execute "INSERT ..."
rs.Open "SELECT @@identity as cou", CurrentProject.Connection
переменная = rs!cou
rs.Close

Однако и этот способ имеет ограничения, а именно:

работает только через ADO, только в Jet 4 и позже, и только с базами формата Аксесса 2000 и позже;

возвращает значение только из записи, добавленной программно, но не через юзер-интерфейс.

A3: Для adp годится такая модификация того же способа:

SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY]

Q9: Как создать одним запросом таблицу со счетчиком?

A: create table xx (id counter)
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32504900
Фотография Владимир Саныч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Опубликовано!
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32504919
sposad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уважаемые, прошу сразу не бить, но позвольте спросить - насколько порочна идея, касающаяся SQL-adp. Принцип состоит в использовании id таблицы SQL server. Т.е. составлять уникальный (???) номер строки, добавляя по 1 к id.
Добавляя не арифметически, а строчно. Просветите пожалуйста, насколько будет уникален такой номер.
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32504923
Фотография Владимир Саныч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Он не будет уникален, потому что два юзера могут одновременно создать одинаковое значение.

А что значит строчно? Типа, если было
11111111111111111111111111111
то добавить 1 и получить
111111111111111111111111111111
?
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32504927
sposad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну да
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32504932
Фотография Владимир Саныч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Но тогда он не только не будет уникальным, но и поле придется под него заводить бешеного размера, и все равно оно быстро кончится. Зачем делать плохо, если можно делать хорошо?
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32504941
sposad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сан Саныч, прошу прошения за неточность, я имел ввиду следующее

ID - 1234
1 строка - 12341
2 строка 12342
3 строка 12343
4 строка 12344
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32504949
sposad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владимир Саныч - я чёкнулся - простите
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32504953
Фотография Владимир Саныч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
А если будет 12349, то дальше 123410? Или 123491?
...
Рейтинг: 0 / 0
FAQ. Что мы знаем про каунтеры (aka счетчики)
    #32504954
sposad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не конец дня и праздник впереди - убить меня мало
...
Рейтинг: 0 / 0
25 сообщений из 176, страница 6 из 8
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / FAQ. Что мы знаем про каунтеры (aka счетчики)
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]