Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Microsoft SQL Server

Автор: Pinocchio
Дата сообщения: 01.08.2006 16:03
Помогите пожалуйста побороть глюк в базе с единственным триггером и единственной таблицей. Вернее в майкросовтовском элементе контроля (Grid) который доступен через "управление компьютером".
Увидеть его очень просто. Создаём новую базу и в ней:
[more]
CREATE TABLE [dbo].[Folders] (
    [Number] [int] NOT NULL ,
    [Owner] [int] NULL ,
    [Name] [varchar] (260) COLLATE Cyrillic_General_CI_AS NULL ,
    [Attr] [int] NULL ,
    [ID] [int] IDENTITY (1, 1) NOT NULL
) ON [PRIMARY]
go

ALTER TABLE [dbo].[Folders] WITH NOCHECK ADD
    CONSTRAINT [PK_Folders] PRIMARY KEY CLUSTERED
    (
        [Number]
    ) ON [PRIMARY]
go

ALTER TABLE [dbo].[Folders] WITH NOCHECK ADD
    CONSTRAINT [DF_Folders_Number] DEFAULT ((-1)) FOR [Number]
go

CREATE TRIGGER [TR_Folders] ON [dbo].[Folders]
INSTEAD OF INSERT
AS
BEGIN
DECLARE @NUM INT
IF ((SELECT [Number] FROM inserted) = -1)
BEGIN
SET @NUM = (SELECT MAX(Number) FROM [Folders])
INSERT INTO [Folders]
SELECT @NUM+1, [Owner], [Name], [Attr]
FROM inserted
END
ELSE
INSERT INTO [Folders]
SELECT [Number], [Owner], [Name], [Attr]
FROM inserted
END
go
[/more]
При вставке когда поле Number стоит цифра то всё работает нормально. Когда добавляем строку в непустую таблицу с пустым полем Number (primary key) строка добавляется, поле Number остаётся пустым, но когда закроем таблицу и откроем заного то там увидим нормальное значение.
Но когда первая строка таблицы имеет в поле Number значение = 0, то тогда при вставке с неуказанным Number возникает глюк - после вставки вместо вставляемой строки мы видим первую строку. Для эксперемента предлагаю вводить в поле Name значения типа aaa ccc bbb и нажимать стрелку вниз. Будет грид с абсолютно одинаковыми строками. Однако когда мы его обновим то будет видно что данные введены вполне корректно.
Автор: KRS545
Дата сообщения: 01.08.2006 17:56
При таком раскладе надо обновлять Грид при каждой вставке, он же не знает что делает триггер на сервере.
А вообще по хорошему нужно убрать триггер, скрыть Number в Гриде, и сделать Number автоинкрементным, и все будет ок

Добавлено:
и еще
IF ((SELECT [Number] FROM inserted) = -1) не очень правильно, т.к. SELECT [Number] FROM inserted может выдать несколько значений при добавлении пакета записей, например при insert select
Автор: Pinocchio
Дата сообщения: 02.08.2006 12:01
KRS545

Цитата:
При таком раскладе надо обновлять Грид при каждой вставке

Это можно как-то сделать средствами SQL? Я имею ввиду, что если бы я пользовал грид из собственной программы то вопросов про Number вообще небыло бы.

Цитата:
он же не знает что делает триггер на сервере.

Вот именно - у него же не возникает подозрений что он посылал NULL в поле которое не может быть NULL. Ты же знаешь, что в компьютере много программ и они потом этот NULL поправляют.

Цитата:
А вообще по хорошему нужно убрать триггер, скрыть Number в Гриде, и сделать Number автоинкрементным

А вот тут поподробнее пожалуйста. Так как ничего не могу найти про термин автоинкремент в хелпах сервера и в книге по программированию MSSQL. Я нашёл IDENTITY и уже использую его, но в других целях (для корректности связей). Думаю понятно что Number это номер и нумерация с 200 тысячь в таблице которую почистили не очень меня радует. А идентификаторы так и работают, тем более их нельзя редактировать. Это уже через чур плохо для человека который собирается использовать базу для уменьшения беспорядка.

Цитата:
IF ((SELECT [Number] FROM inserted) = -1) не очень правильно

Естественно что это не правильно, однако посылать пакет записей с NULL значениями для примари полей никто не собирался вроде. SQL устраивает, не устраивала работа грида в ситуации когда первая запись в таблице имеет номер равный нулю.

Добавлено:
Чем хорош триггер - это тем что его перед пакетной вставкой можно DROB а после вставки CREATE (это позволяет программе иметь туже производительность, а после отработки иметь защиту от пользователя "управления компьютером"). Честно говоря хотел состряпать небольшой сервис(службу) который бы запрещал удаление (редактирование) файлов занесённых в таблицу. Сделал ещё проще - не через триггер а через функцию - те же глюки. Дело видимо не в SQL. Вот код:

Код:

CREATE FUNCTION MN_Folders ()
RETURNS int
AS
BEGIN
DECLARE @NUM INT
SET @NUM = (SELECT MAX(Number) FROM [Folders])
RETURN(@NUM+1)
END
go


ALTER TABLE [dbo].[Folders] ADD
    CONSTRAINT [DF_Folders_Numer] DEFAULT ([dbo].[MN_Folders]()) FOR [Number]
go

Автор: KRS545
Дата сообщения: 02.08.2006 15:45
Под автоинкрементом имел ввиду как раз IDENTITY
Вообще не совсем понял какую цель вы преследуете.
Можно поподробнее... А потом будем думать как проще это сделать.

Автор: Pinocchio
Дата сообщения: 02.08.2006 17:48
KRS545
Допустим я разрешил жене удалять записи с tv тюнера, но те файлы которые удалять нельзя "зашарены", так как атрибут редонли не отдаляет процесс удаления файла даже на один клик окея.
Если список шареных файлов хранить в базе то такой вариант очень удобен - так как лесть в базу будет лень. Логично?
Тем более что программу снимающую карту диска в базу я уже написал. ID использую для того чтобы ссылки иерархии каталогов велись базой автоматически. А вот нумерация влияющая на порядок записей по ID меня не привлекает.

Добавлено:
Номер это нумер и по логике если последняя запись в таблице нумерована максимальным числом то новую запись логичнее всего представить с номером большим на единицу.
Автор: KRS545
Дата сообщения: 02.08.2006 18:14
Pinocchio
Че то не совсем врубился, особенно про карту диска, ссылки иерархии каталогов, и что помешает все-таки удалить файлы с диска напрямую.

логичнее всего представить с нумером большим на единицу
ну и сделайте его IDENTITY
Автор: Pinocchio
Дата сообщения: 03.08.2006 11:39
KRS545

Цитата:
Че то не совсем врубился, особенно про карту диска, ссылки иерархии каталогов, и что помешает все-таки удалить файлы с диска напрямую.

Когда файл открыт эксклюзивно типа "*.mdf" то его удалить сложнее.

Цитата:
ну и сделайте его IDENTITY

Спасибо за совет, к сожалению мы на разных языках видимо разговариваем. На моём языке идентификатор это идентификатор, а номер это номер. Мне трудно улавливать Ваш юмор, мне нужен был совет, или время. Оказалось второе. После того как понял, что мне необязательно видеть в гриде то, что идёт до первого номера всё встало на свои места. Пока я ввел ограничение. А когда будут более тонкие материи, будет вполне очевидно, почему не только мне приходится избегать применения нулевых значений.
[more]
CREATE FUNCTION MN_Folders ()
RETURNS int
AS
BEGIN
DECLARE @MN int
IF (SELECT MAX([Number]) FROM [dbo].[Folders]) > 0
BEGIN
SET @MN=(SELECT MAX([Number]) FROM [dbo].[Folders])+1
END
ELSE SET @MN=1
RETURN(@MN)
END
go

ALTER TABLE [dbo].[Folders] WITH NOCHECK ADD
    CONSTRAINT [DF_Folders_Number] DEFAULT ([dbo].[MN_Folders]()) FOR [Number],
    CONSTRAINT [CK_Folders] CHECK ([Number] > 0)
go
[/more]
Понимаю, что это только визуальный эффект, однако прикольный.
Автор: Pinocchio
Дата сообщения: 08.08.2006 11:24
Мой вопрос похоже закрылся. Показал всё как есть. Вобщем ей понравилось, но интерпретация была однозначной - этот эффект глюк. Так же она поняла почему для нас такие моменты большая ценность.
Автор: TitanMK
Дата сообщения: 28.08.2006 11:25
Мож такое у кого было.
Вообщем мне срочно нужена помощь....
сатвлю сиквел 2005 Ent собраный как написано в варезнике... при установке винда кидает при установке компонентов Books Online, менеджмент студио вот ето С:\windows\instaler3A7C7.msi was rejected by digital signature policy....че за хрень... до етого ставил на 2003 SP1 было все ОК. Ставлю на систему Win2003 SP1 + R2
и все.. нече не ставится... в логах таже ошибка
Автор: djdtyfhu
Дата сообщения: 10.09.2006 03:05
Есть файл. Пусть называется KadrFull.BAK первые байты выглядят так:
"TAPE  Њ   ‡Ѕ(–    , ^  T{l{M i c r o s o f t S Q L S e r v e r SPAD ^ L"

далее есть строчка:
" K a d r s b a c k u p s a SPAD R @ "

как я понимаю это бэкап базы данных в формате MS SQL Server
Подскажите как можно восстановить исходную базу и просмотреть данные

P.S. Кроме этого файла есть сформированные запросы и сам запускальщик оболочки.
На компьютере установлен только Delphi 5 без самого MS SQL Server.
Автор: naPmu3aH
Дата сообщения: 10.09.2006 04:21
djdtyfhu

Цитата:
без самого MS SQL Server

Ну и куда в таком случае восстанавливать базу?
Автор: darmoedina
Дата сообщения: 20.09.2006 15:57
Здравствуйте.
Помогите составить запрос, чтобы данные из одного 2 столбца скопировались в 1 столбец кроме тех ячеек которые уже заполнены в 1 столбце. Или с синтаксиса какого оператора надо начать?
Автор: gerrCrazzy
Дата сообщения: 20.09.2006 16:11
darmoedina

Цитата:
кроме тех ячеек которые уже заполнены в 1 столбце

гм.. что значит не заполнены? равны 0, пустой строке или null?
ниже пример для null

Цитата:
Или с синтаксиса какого оператора надо начать?


Код:
UPDATE [имя_таблицы]
SET [столбец1] = [столбец2]
WHERE [столбец1] is null
Автор: darmoedina
Дата сообщения: 21.09.2006 09:40

Цитата:
гм.. что значит не заполнены? равны 0, пустой строке или null?

Для пустой строки
зы где можно прочесть какие значения можно подставлять?

Добавленно:
При попытке задать пустую строку "" пишет

Код:
Msg 1038, Level 15, State 4, Line 3
An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Add a name or single space as the alias name.
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near ''.
Автор: SJS
Дата сообщения: 26.09.2006 04:06
Здравствуйте. Помогите или намекните , как сделать КОД для триггера из sql запросов идущих от MSAccess'a:


--Query1
SELECT dbo.T_USER_INSIDE.USER_DATA, dbo.T_USER_INSIDE.USER_KEY, dbo.T_USER_INSIDE.TASK_NUM
FROM dbo.T_USER_INSIDE
GROUP BY dbo.T_USER_INSIDE.USER_DATA, dbo.T_USER_INSIDE.USER_KEY, dbo.T_USER_INSIDE.TASK_NUM
HAVING (((dbo.T_USER_INSIDE.USER_DATA) Is Not Null) AND ((dbo.T_USER_INSIDE.USER_KEY) Is Not Null)
AND ((dbo.T_USER_INSIDE.TASK_NUM)=123));

--Query2
SELECT dbo.T_USER_INSIDE.USER_ID, Sum(dbo.T_USER_INSIDE.TASK_NUM)
AS [Sum-TASK_NUM], dbo.T_USER_INSIDE.USER_SPID
FROM dbo.T_USER_INSIDE
GROUP BY dbo.T_USER_INSIDE.USER_ID, dbo.T_USER_INSIDE.USER_SPID
HAVING (((Sum(dbo.T_USER_INSIDE.TASK_NUM))=0));

--Query3....
INSERT INTO dbo.T_USER_INSIDE ( USER_ID, USER_SPID, USER_DATA, USER_KEY, TASK_NUM )
SELECT Query2.USER_ID, Query2.USER_SPID, Query1.USER_DATA, Query1.USER_KEY, Query1.TASK_NUM
FROM Query2, Query1;

Прошу наверно много...но может кто из специалистов подскажет
Автор: vladk1973
Дата сообщения: 26.09.2006 06:34

Цитата:
Помогите или намекните , как сделать КОД для триггера из sql запросов идущих от MSAccess'a:

Читал, и не понял ни одной буквы...
Нельзя ли подробнее указать, что конкретно надо получить и причем тут MS SQL Server
Автор: SJS
Дата сообщения: 26.09.2006 16:01
vladk1973

это sql запросы к серверу из приложения на изменение значений одной таблицы, если изменения insert, delete в ней произошли, лучше это, мне так кажеться, сделает триггер к этой таблице...
но код триггера будет выглядеть несколько иначе чем эти sql запросы...ну не силён я в триггерах
Автор: vladk1973
Дата сообщения: 27.09.2006 01:58
SJS
Триггеры могут обрабатывать только команды DML
На SELECT триггер не поставишь - здесь надо смотреть в сторону представления (create view...)
Первые два запроса можно смело оформить в виде представления
На команду INSERT - триггер на таблицу T_USER_INSIDE, пожалуйста, ставь. Только зачем он тебе?
Сама команда INSERT будет выглядеть как
INSERT ***
SELECT *** FROM view1, view2

Я понимаю, что ничего не понимаю, нельзя ли цель этих трех запросов указать ?

Добавлено:
darmoedina

Цитата:
Msg 1038, Level 15, State 4, Line 3
An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Add a name or single space as the alias name.
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near ''.

Код команды UPDATE пожалуйста в студию. Подозреваю, что пишешь
WHERE [столбец1] IS ''
Автор: SJS
Дата сообщения: 27.09.2006 03:36
vladk1973 и darmoedina

я понимаю что код который тут поместил...немного запутал вас
Хорошо попробую так задачу обрисовать словами :
есть таблица в базе sql (ниже не код)
dbo.T_USER_IN ( ID, NUM, SPID, HOST, DATA,KEY)
внешнее приложение замисывет строку (insert)
dbo.T_USER_IN ( ID, NUM="0", SPID, HOST, DATA,KEY)
надо чтобы эта строка записалась в таблицу, а триггер (после )
если записывается NUM="0", создал бы аналогичную 1 запись, но в ней
NUM ="3" например, DATA=10 и KEY = "077"




Добавлено:
я понимаю что тут надо работать с таблицей inserted,
а потом выпонить команду Insert...но это у меня не получается - собрать в "кучу"
Автор: vladk1973
Дата сообщения: 27.09.2006 04:19
Здесь самый лучший способ, имхо - опять же через вьюшку
create view [T_USER_INview] as select ID, NUM, SPID, HOST, DATA,KEY from T_USER_IN
Триггер вешать именно на эту вьюшку
В триггере уже делать вставку в саму таблицу T_USER_IN

Из приложения вставлять строки не в T_USER_IN, а во вьюшку [T_USER_INview]

В самом триггере - все элементарно
Сначала простой
INSERT INTO T_USER_IN тра-та-та
SELECT тра-та-та FROM inserted
Затем еще один
INSERT INTO T_USER_IN тра-та-та
SELECT тра-та-та FROM inserted WHERE NUM='0'
Автор: darmoedina
Дата сообщения: 28.09.2006 07:25

Цитата:

darmoedina

Цитата: Msg 1038, Level 15, State 4, Line 3
An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Add a name or single space as the alias name.
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near ''.

Код команды UPDATE пожалуйста в студию. Подозреваю, что пишешь
WHERE [столбец1] IS ''

Автор: Solnake
Дата сообщения: 28.09.2006 08:23
darmoedina
пустую -
where
поле=''

нулевую -
where
поле is null
Автор: SJS
Дата сообщения: 28.09.2006 15:21
vladk1973
Большущее спасибо! Это всё заработало через вьюшку, но возникла ещё одна просьба по режиму удаления (да не покажусь я назойливым и т.п ...)

При попытке удаления приложением одной строки из T_USER_INview:
если NUM <> '0' - блокировать удаление (не удалять)
если NUM =0 - удалить

При попытке удаления приложением 2-x и более строк
из T_USER_INview - удалять (не мешать)

=вот такая просьба


Автор: vladk1973
Дата сообщения: 29.09.2006 03:21
SJS
Тут, естественно, тоже триггер нужОн
На удаление соответственно. Вешаешь его на вьюшку T_USER_INview
В триггере простейшая конструкция, на вскидку что то типа


Код:
IF (SELECT COUNT(*) FROM deleted) = 1
DELETE a
FROM T_USER_INSIDE a INNER JOIN deleted d ON a.ID = d.ID AND тра-та-та
WHERE d.NUM = 0
ELSE
DELETE a
FROM T_USER_INSIDE a INNER JOIN deleted d ON a.ID = d.ID AND тра-та-та
Автор: u3ver
Дата сообщения: 29.09.2006 09:21
Добрый день всем.
как поставить sql2005ee на win xp? по моему нужен mdac, да?
Автор: SJS
Дата сообщения: 30.09.2006 00:09
vladk1973
спасибо!
всё сделал... ставил на вьюшку, но получилось и на таблицу 2 триггера insert на Instead Of а на удаление сделал на After

IF @@ROWCOUNT=1 -- если удалена одна запись
BEGIN
SELECT @m_t=NUM FROM deleted
IF @m_t > 0 -- если не ноль в удаляемой строке
BEGIN
-- возвращаем удяляемую строку в таблицу
INSERT INTO dbo.T_USER_INSIDE (тра та-та)
SELECT тра-та-та FROM deleted
END
END
END

вообщем Огромное спасибо!
Автор: raeye
Дата сообщения: 30.09.2006 01:41

Цитата:
u3ver


Цитата:
как поставить sql2005ee на win xp? по моему нужен mdac, да?

А в дистрибутив он разве не входит?
А вообще, если у тебя стоит MSOfiice, то MDAC уже установлен
Автор: vladk1973
Дата сообщения: 02.10.2006 02:32
u3ver

Может я и ошибаюсь, но mdac стоит по умолчанию в XP
Автор: u3ver
Дата сообщения: 19.10.2006 17:05
2005ee не ставиться на хп, только стандарт
еще один очень важный вопросик:
поставил sql 2005 ee. потом снес не корректно. теперь такая ситуация, что ни поставить, ни удалить его остатки нельзя короче засада по полной
как бы удалить sql2005? может есть какая утилита по удалению или с каким то ключиком запустить ехе?
Автор: N9
Дата сообщения: 27.10.2006 09:05
Подскажите пожалуйста, у нас MS SQL server 7.0. В Enterprise Manager в Management\Database Maintenance Plans создано задание на ежедневный бэкап базы, но в директории для бэкапа можно выбрать только диски C и D, а сетевых дисков нет. Есть ли возможность делать ежедневный бекап на сетевой диск?

Страницы: 1234567891011121314151617181920212223242526272829

Предыдущая тема: Генератор 10-ти разрядных ключей


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.