Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Вопрос про транзакции и хранимые процедуры  [new]
Aa
Member

Откуда:
Сообщений: 13
Здравствуйте!
У меня вот такой вопрос.
Есть в SQL Server 2000 две таблицы. В №1 содержатся основные сведения. В № 2 - дополнительные. Сначала нужно записать одно сведение в таблицу №1. Затем, в цикле, сколько надо - дополнительные сведения в №2. Причем если выполнение записи в таблицу №2 неудачно на одном из шагов, то откат по обеим таблицам.
Вопрос вот в чем. Я не знаю как передавать с клиентского приложения (Access) в хранимую процедуру параметры в цикле. Я имею в виду, что таблицы зависимы (логически, а так между ними нет связи), и вообще, как сделать такую транзакцию?
Наверное вопрос глупый, но я не знаю как это все сделать. Если меня кто-нибудь понял, то подскажите, пожалуйста. Если не поняли - могу уточнить :)
Заранее спасибо.
3 июн 03, 13:00    [219937]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос про транзакции и хранимые процедуры  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
1.А это принципиально, чтобы в цикле писать данные из акцесса на эскуэль?
2.Через что коннектишся с сервером из акцесса (адо, одибиси)?
3 июн 03, 13:13    [219973]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос про транзакции и хранимые процедуры  [new]
Crimean
Member

Откуда:
Сообщений: 13148
В таблице 1 сделать поле "статус"
И записи из нее не читать, если статус не "нормальный"
Статус "нормальный" ставить только по окончанию вставок в 2
Чтобы ничего не ломать все разводится триггерами и вьюхами
Транзакцию выкинуть
Проблема отправки пакета данных автоматом снимается
3 июн 03, 13:48    [220064]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос про транзакции и хранимые процедуры  [new]
Aa
Member

Откуда:
Сообщений: 13
2 tpg
1. Да нет, конечно. А как мне бы передать целую таблицу данных. Я имею в виду, клиент собрал у себя кучу данных и хочет их переслать. Как это дело организовать? Возможно запихать в параметр хранимой процедуры неопределенное кол-во данных?
2. Ессно, через ADO.


2 Crimean.
Круто... Подумаю...
4 июн 03, 16:10    [221742]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос про транзакции и хранимые процедуры  [new]
Crimean
Member

Откуда:
Сообщений: 13148
Это не круто :(
Это возврат к DBF, мать его...
Бо с транзакциями, как оказалось, такая ж...
Вот я у себя и хреначу почти во всех таблицах поле "удален" , да еще и в уникальность его, временами, включаю...
4 июн 03, 16:16    [221758]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос про транзакции и хранимые процедуры  [new]
Aa
Member

Откуда:
Сообщений: 13
>Это не круто :(
Вполне может быть, но я бы до такого не додумалась, если честно.

Так. А теперь я не могу додуматься как мне от клиента передать целую таблицу (что-то у меня сегодня ничего не варит, за что не возьмусь - куча вопросов, но одного решения .

Есть идеи?
4 июн 03, 16:56    [221841]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос про транзакции и хранимые процедуры  [new]
Glory
Member

Откуда:
Сообщений: 104760
Читайте рассылку.
4 июн 03, 17:04    [221852]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос про транзакции и хранимые процедуры  [new]
Aa
Member

Откуда:
Сообщений: 13
2 Glory
Спасибо, вы так любезны!
4 июн 03, 17:13    [221870]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос про транзакции и хранимые процедуры  [new]
Glory
Member

Откуда:
Сообщений: 104760
Я имел ввиду последний выпуск рассылки данного сайта. А не вообще
4 июн 03, 17:18    [221877]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос про транзакции и хранимые процедуры  [new]
Aa
Member

Откуда:
Сообщений: 13
Тогда прошу прощения. Обычно новичкам типа меня или не отвечают, или дают размытые советы типа "читай книжки". Совет, конечно дельный, но не всегда правильный, особенно когда чел за помощью именно к ЛЮДЯМ, а не книжкам обращается... Что-то типа того. С выражением мыслей у меня сегодня тоде бардак
4 июн 03, 17:20    [221884]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос про транзакции и хранимые процедуры  [new]
Salik
Member

Откуда:
Сообщений: 297
Poprobuy tak
alter procedure AddDetails

@id int
, @DetailsXML ntext

as

declare @hdoc int

exec sp_xml_preparedocument @hdoc out, @DetailsXML
select
@ID as ID
, *
into #temptable from openxml(@hdoc,'/PLATFORMS/PLATFORM',3)
with ( PLATID bigint ,
REDIRECT_URL varchar(100) )

EXEC sp_xml_removedocument @hdoc
select * from #temptable
go





exec AddDetails 2
,'
<PLATFORMS>
<PLATFORM PLATID="1" REDIRECT_URL="\\SJHJHCOM\RRR.DEFAULT 1"/>
<PLATFORM PLATID="2" REDIRECT_URL="\\SJHJHCOM\RRR.DEFAULT 2"/>
<PLATFORM PLATID="3" REDIRECT_URL="\\SJHJHCOM\RRR.DEFAULT 3"/>
</PLATFORMS>'
4 июн 03, 17:32    [221917]     Ответить | Цитировать Сообщить модератору
 Re: Вопрос про транзакции и хранимые процедуры  [new]
superbluesman
Member

Откуда:
Сообщений: 1017
to Aa:

привожу полностью свою функцию как перелить записи ЗА ОДИН раз из Access-таблицы во временную или постоянную таблицу на SQL-сервере. У себя я её тестировал, работает.
Изучайте код, полагаю, разберётесь :-)




Public Function QuickRowsToSql(pc_SourceTblName As String, pc_TargetTblName As String, _
pl_ReCreateTbl As Boolean, pc_WhereExp As String, _
ParamArray parr_Spprm() As Variant) As Integer
' Выполняет перелив записей через ODBC (ЗА ОДИН раз) из Access-таблицы во временную или постоянную таблицу на сервере
' pc_SourceTblName - имя Access-таблицы откуда переливаются записи
' pc_TargetTblName - имя таблицы-назначения (временная или постоянная) на SQL-сервере
' pl_ReCreateTbl - пересоздание (=True) таблицы назначения на сервере
' pc_WhereExp - строка-критерия отбора записей для перелива
' parr_Spprm() - массив имён полей Access-таблицы, значения которых надо перелить на сервер,
' если не указан, то берутся все поля источника
'
' Возвращает: 1 - перелив выполнен успешно
' 0 - в случае какой-либо ошибки на сервере при попытке перелива данных
' -1 - в случае какой-либо ошибки на сервере при пересоздании Target-таблицы
' -2 - не удаётся установить соединение с сервером
' -3 - не существует указанной Access-таблицы
' -4 - в случае какой-либо ошибки при формировании строки-Pass-команды пересоздания Target-таблицы
' -5 - в случае какой-либо ошибки при формировании строки-Pass-команды для перелива данных
' -6 - не указан какой-либо из первых трёх обязательных параметров данной функции
Dim dbsCurrent As Database, qdfPassThrough As QueryDef, lc_QuertySQLName As String, _
ln_Low As Integer, ln_High As Integer, lnCntFld As Integer, lc_SelFld As String, _
lc_InsFld As String, lcS As String, lnP As Integer, lc_FromMDBFile As String

If Len(pc_SourceTblName) < 1 Or Len(pc_TargetTblName) < 1 Then
QuickRowsToSql = -6
End If
If CheckTable(pc_SourceTblName) = False Then
QuickRowsToSql = -3
Exit Function
End If
If OpenConnect = False Then
QuickRowsToSql = -2
Exit Function
End If

On Error GoTo ErrorHandler0
Screen.MousePointer = 11
Set dbsCurrent = CurrentDb()
lc_QuertySQLName = "tmp_to"
If CheckQuery(lc_QuertySQLName) Then
Set qdfPassThrough = dbsCurrent.QueryDefs(lc_QuertySQLName)
Else
Set qdfPassThrough = dbsCurrent.CreateQueryDef(lc_QuertySQLName)
End If

ln_High = UBound(parr_Spprm())
If pl_ReCreateTbl Then
If Left(pc_TargetTblName, 1) = "#" Then
lcS = "IF object_id('tempdb.." & pc_TargetTblName & "') IS NOT NULL DROP TABLE " & pc_TargetTblName
Else
lcS = "IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'dbo." & pc_TargetTblName & "') AND OBJECTPROPERTY(id, N'IsUserTable') = 1) DROP TABLE dbo." & pc_TargetTblName
End If
lcS = lcS & " CREATE TABLE " & pc_TargetTblName & " ("
With dbsCurrent.TableDefs(pc_SourceTblName)
If ln_High > -1 Then
For ln_Low = 0 To ln_High
Select Case .Fields(parr_Spprm(ln_Low)).Type
Case dbText
lcS = lcS & " " & .Fields(parr_Spprm(ln_Low)).name & " CHAR(" & CStr(.Fields(parr_Spprm(ln_Low)).Size) & "),"
Case dbMemo
lcS = lcS & " " & .Fields(parr_Spprm(ln_Low)).name & " TEXT,"
Case dbBoolean
lcS = lcS & " " & .Fields(parr_Spprm(ln_Low)).name & " BIT,"
Case dbByte
lcS = lcS & " " & .Fields(parr_Spprm(ln_Low)).name & " TINYINT,"
Case dbInteger
lcS = lcS & " " & .Fields(parr_Spprm(ln_Low)).name & " SMALLINT,"
Case dbLong
lcS = lcS & " " & .Fields(parr_Spprm(ln_Low)).name & " INT,"
Case Date
lcS = lcS & " " & .Fields(parr_Spprm(ln_Low)).name & " DATETIME,"
Case dbCurrency
lcS = lcS & " " & .Fields(parr_Spprm(ln_Low)).name & " MONEY,"
Case dbSingle, dbDouble, dbDecimal
lcS = lcS & " " & .Fields(parr_Spprm(ln_Low)).name & " NUMERIC(18,6),"
End Select
Next ln_Low
Else
lnCntFld = .Fields.Count
For ln_Low = 0 To lnCntFld - 1
Select Case .Fields(ln_Low).Type
Case dbText
lcS = lcS & " " & .Fields(ln_Low).name & " CHAR(" & CStr(.Fields(ln_Low).Size) & "),"
Case dbMemo
lcS = lcS & " " & .Fields(ln_Low).name & " TEXT,"
Case dbBoolean
lcS = lcS & " " & .Fields(ln_Low).name & " BIT,"
Case dbByte
lcS = lcS & " " & .Fields(ln_Low).name & " TINYINT,"
Case dbInteger
lcS = lcS & " " & .Fields(ln_Low).name & " SMALLINT,"
Case dbLong
lcS = lcS & " " & .Fields(ln_Low).name & " INT,"
Case Date
lcS = lcS & " " & .Fields(ln_Low).name & " DATETIME,"
Case dbCurrency
lcS = lcS & " " & .Fields(ln_Low).name & " MONEY,"
Case dbSingle, dbDouble, dbDecimal
lcS = lcS & " " & .Fields(ln_Low).name & " NUMERIC(18,6),"
End Select
Next ln_Low
End If
End With
lcS = IIf(Right(lcS, 1) = ",", Left(lcS, Len(lcS) - 1), lcS) & ")"
qdfPassThrough.Connect = pc_ODBCSqlConnection
qdfPassThrough.ReturnsRecords = False
qdfPassThrough.SQL = lcS
'MsgBox lcS
On Error GoTo ErrorHandler1
dbsCurrent.QueryDefs(lc_QuertySQLName).Execute
End If

On Error GoTo ErrorHandler2
If ln_High > -1 Then
For ln_Low = 0 To ln_High
lc_SelFld = lc_SelFld & " " & parr_Spprm(ln_Low) & ","
lc_InsFld = lc_InsFld & " " & parr_Spprm(ln_Low) & ","
Next ln_Low
lc_SelFld = IIf(Right(lc_SelFld, 1) = ",", Left(lc_SelFld, Len(lc_SelFld) - 1), lc_SelFld)
lc_InsFld = "(" & IIf(Right(lc_InsFld, 1) = ",", Left(lc_InsFld, Len(lc_InsFld) - 1), lc_InsFld) & ")"
Else
With dbsCurrent.TableDefs(pc_SourceTblName)
lnCntFld = .Fields.Count
For ln_Low = 0 To lnCntFld - 1
lc_SelFld = lc_SelFld & " " & .Fields(ln_Low).name & ","
Next
lc_SelFld = IIf(Right(lc_SelFld, 1) = ",", Left(lc_SelFld, Len(lc_SelFld) - 1), lc_SelFld)
lc_InsFld = "(" & lc_SelFld & ")"
End With
End If
pc_WhereExp = Trim(pc_WhereExp)
pc_WhereExp = IIf(Left(pc_WhereExp, 5) = "WHERE", "", IIf(Len(pc_WhereExp) > 0, "WHERE ", "")) & pc_WhereExp

' полное имя, включая UNC-путь и расширение, к MDB-файлу, в котором находится таблица,
' из которой будут переливаться записи, например, \\410infprogns\ANDERRATING\ACCESS\anderrating.mdb
' ВАЖНО!!! UNC-путь к MDB-файлу определяется относительно от SQL-сервера !!!
lc_FromMDBFile = pc_PathFromServerApp + OnlyDbName()

lcS = "INSERT INTO " & pc_TargetTblName & " " & lc_InsFld & " SELECT " & lc_SelFld & _
" FROM OPENROWSET('Microsoft.Jet.OLEDB.4.0', '" & lc_FromMDBFile & "';'admin';'', " _
& pc_SourceTblName & ") " & pc_WhereExp
'MsgBox lcS
qdfPassThrough.Connect = pc_ODBCSqlConnection
qdfPassThrough.ReturnsRecords = False
qdfPassThrough.SQL = lcS
On Error GoTo ErrorHandler3
dbsCurrent.QueryDefs(lc_QuertySQLName).Execute
QuickRowsToSql = 1

ExitHere:
Screen.MousePointer = 0
Set dbsCurrent = Nothing
qdfPassThrough.Close
Set qdfPassThrough = Nothing
Exit Function

ErrorHandler0:
On Error GoTo 0
QuickRowsToSql = -4
Resume ExitHere

ErrorHandler1:
On Error GoTo 0
QuickRowsToSql = -1
Resume ExitHere

ErrorHandler2:
On Error GoTo 0
QuickRowsToSql = -5
Resume ExitHere

ErrorHandler3:
On Error GoTo 0
QuickRowsToSql = 0
MsgBox "Ошибка при переливе данных на сервер из таблицы " & pc_SourceTblName & _
" (" & lc_FromMDBFile & "). Возможно сервер не может получить доступ к указанной Access-таблице" & _
IIf(pl_ReCreateTbl, "", " или не существует/сбой в таблице назначения"), vbCritical + vbOKOnly, " "
Resume ExitHere
End Function
4 июн 03, 19:14    [222033]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить