2010-01-04 2 views
0

Хорошо. У меня есть ситуация, когда я должен выполнить динамически построенную хранимую процедуру для таблиц, которые могут или не могут быть в базе данных. Полученные данные затем шунтируются на странице отчета на основе ASP на основе VB.Net. По дизайну, если таблицы не присутствуют в базе данных, соответствующие данные автоматически скрываются на странице отчета. В настоящее время я делаю это, проверяя неизбежную ошибку и скрывая div в блоке catch. Немного клочья, но это сработало.Предпочтительный метод для улавливания специфической ошибки OleDB

Я не могу включить код VB-кода, но соответствующая хранимая процедура приведена ниже.

Однако проблема с этим методом была недавно привлечена к моему вниманию, когда, без всякой видимой причины, div был скрыт, даже если соответствующие данные были доступны. Как выяснилось, пользователь, пытающийся выбрать таблицу в динамическом вызове SQL, не имел надлежащих разрешений выбора, достаточно простого исправления, как только я смог бы его отслеживать.

Итак, в два раза вопрос. В первую очередь - есть ли лучший способ проверить недостающую таблицу, чем перехватить ошибку в коде VB.Net? Все, что было рассмотрено, я бы предпочел сохранить проверку ошибок для фактической ошибки. Во-вторых, существует ли предпочтительный способ выкидывать конкретную ошибку OLE DB из общего объекта, захваченного блоком try-> catch, кроме проверки фактической строки трассировки стека?

SQL Query - основной смысл кода заключается в том, что из-за дизайна базы данных мне нужно определить имя фактической таблицы, предназначенной вручную. База данных записывает задания в одну таблицу, но каждое задание также получает свою собственную таблицу для обработки данных по элементам, обрабатываемым в этом задании, и это данные из тех таблиц, которые мне нужно получить. К сожалению, я ничего не могу с этим поделать.

DECLARE @sql     NVarChar(Max), 
      @params    NVarChar(Max), 
      @where    NVarChar(Max) 

-- Retained for live testing of stored procedure. 
-- DECLARE @Table NvarChar(255) SET @Table = N'tblMSGExportMessage_10000' 
-- DECLARE @AcctID Integer SET @AcctID = 10000 
-- DECLARE @Type Integer SET @Type = 0 -- 0 = Errors only, 1 = All Messages 
-- DECLARE @Count Integer 

-- Sets our parameters for our two dynamic SQL calls. 
SELECT @params = N'@MsgExportAccount INT, @cnt INT OUTPUT' 

-- Sets our where clause dependent upon whether we want all results or just errors. 
IF @Type = 0 
    BEGIN 
      SELECT @where = 
      N' AND (mem.[MSGExportStatus_OPT_CD] IN (11100, 11102) ' + 
      N'  OR mem.[IngestionStatus_OPT_CD] IN (11800, 11802, 11803) ' + 
      N'  OR mem.[ShortcutStatus_OPT_CD] IN (11500, 11502)) ' 
    END 
ELSE 
    BEGIN 
      SELECT @where = N' ' 
    END 

-- Retrieves a count of messages. 
SELECT @sql = 
N'SELECT @cnt = Count(*) FROM dbo.' + QuoteName(@Table) + N' AS mem ' + 
N'WHERE mem.[MSGExportAccount_ID] = @MsgExportAccount ' + @where 

EXEC sp_executesql @sql, @params, @AcctID, @cnt = @Count OUTPUT 

ответ

1

Чтобы избежать ошибки, вы можете запросить таблицу sysobjects, чтобы узнать, существует ли таблица. Вот SQL (замените YourTableNameHere). Если он возвращает> 0, то таблица существует. Создайте процедуру хранения на сервере, который выполняет этот запрос.

select count(*) 
from sysobjects a with(nolock) 
where a.xtype = 'U' 
    and a.name = 'YourTableNameHere' 
+0

Знаешь, я видел, что этот код очень похож - слишком много раз, чтобы отсчет сгенерированных скриптов из SQL Management Studio. Вы могли бы подумать, что это, возможно, прошло через мой толстый череп, так это то, как вы проверяете, существует ли таблица (или любой объект) ... Хех, спасибо, что помогли сбить очевидное, я не могу поверить, что я пропустил это. – Clyde

Смежные вопросы