Просто построив приложение C# для запуска SQL-скриптов, я столкнулся с несколькими проблемами с обработкой ошибок.Ошибка TSQL в .Net, но не в SSMS
У нас есть хранимая процедура в нашей базе данных, которая изменяет ограничение по умолчанию для таблиц (путем удаления любого существующего, а затем создания нового), и оно отлично работает, когда мы вызываем его из SSMS. Однако, когда мы вызываем ту же самую хранимую процедуру из .Net SqlClient, она дает ошибку. Я получаю ошибку в SqlException
имеет сообщение:
System.Data.SqlClient.SqlException: Column already has a DEFAULT bound to it.
Could not create constraint. See previous errors.
Это не должно произойти, так как мы никогда не видим сообщение в SSMS, если мы не запустить заявление падение первого. Если заявление Drop Constraint
закомментировано, мы видим одно и то же сообщение.
Почему ограничение не будет удалено при вызове хранимой процедуры из .Net?
Для справки, соответствующий код внутри хранимой процедуры:
SELECT @strSQL = 'ALTER TABLE [' + @strTableName + '] DROP CONSTRAINT [' + @strConstraintName + ']'
EXEC sp_executesql @strSQL
SELECT @strSQL = 'ALTER TABLE [' + @strTableName + '] ADD CONSTRAINT DF_' + @strTableName + '_' + @strColumnName + ' DEFAULT (' + @strDefaultValue + ') FOR ' + @strColumnName
EXEC sp_executesql @strSQL
EDIT: Я считал захват на наличие ошибок, и игнорирование не фатальные ошибки, такие как это. Однако, к сожалению, эта конкретная ошибка является ошибкой уровня 16, и такие ошибки, как обновление несуществующей таблицы, - это только уровень 15. Поэтому я не могу позволить этой ошибке проходить, фильтруя класс ошибок исключения.
EDIT 2: Если бы было сказано, @strConstraintName
определяется автоматически на основе имени таблицы и столбца:
SELECT
@strConstraintName = vdc.CONSTRAINT_NAME
FROM
dbo.vw_DEFAULT_CONSTRAINT vdc
WHERE
vdc.TABLE_NAME = @strTableName
AND vdc.COLUMN_NAME = @strColumnName
Разрешение
Таким образом, получается, что vw_DEFAULT_CONSTRAINT, что определяло имя ограничения по умолчанию было плохо написано.
По какой-то причине он был основан на значении USER_ID() (представление было написано до того, как я начал), что не было необходимо. Удаление этого ограничения из представления вернуло правильное имя ограничения.
@ Ответ ErikE обеспечил хороший толчок в правильном направлении. Сохранение значений переменных во временную таблицу позволило мне увидеть, что эти два метода не работают одинаково, что привело меня к дальнейшему изучению представления. Престижность к @ErikE для этого, поэтому я выбрал его как правильный ответ.
Мне кажется странным, что значение USER_ID() не было одинаковым, поскольку соединения были идентичными.
Имеет ли пользователь C# те же привилегии, что и пользователь SSMS? –
@ron tornambe - соединение использует те же учетные данные, поэтому да, это точно то же самое –
Кроме того, пользователь является владельцем базы данных, поэтому имеет полные права на него –