最初の実行時にアクセス許可について文句を言わずに実行されるストアド プロシージャを使用しています。ストアド プロシージャには、UID/PWD が 1 つしか設定されていません (さまざまなアクセス許可レベルを付与するための UID/PWD のさまざまなセットはありません)。単一のペアはすべてに許可を与えます。
ストアド プロシージャを呼び出す私のコードは次のとおりです。
DataTable dtPriceComplianceResults
SQLDBHelper.ExecuteSQLReturnDataTable(PriceComplianceConstsAndUtils.SUMMARY_STOREDPROC, CommandType.StoredProcedure,
new SqlParameter()
{
ParameterName = "@BegDate",
SqlDbType = SqlDbType.VarChar,
Value = _begDateStr
},
new SqlParameter()
{
ParameterName = "@EndDate",
SqlDbType = SqlDbType.VarChar,
Value = _endDateStr
},
new SqlParameter()
{
ParameterName = "@Member",
SqlDbType = SqlDbType.VarChar,
Value = _member
},
new SqlParameter()
{
ParameterName = "@Unit",
SqlDbType = SqlDbType.VarChar,
Value = _unit
});
public static DataTable ExecuteSQLReturnDataTable(string sql, CommandType cmdType, params SqlParameter[] parameters)
{
using (DataSet ds = new DataSet())
using (SqlConnection connStr = new SqlConnection(PriceComplianceConstsAndUtils.CPSConnStr))
using (SqlCommand cmd = new SqlCommand(sql, connStr))
{
cmd.CommandType = cmdType;
cmd.CommandTimeout = EXTENDED_TIMEOUT;
foreach (var item in parameters)
{
cmd.Parameters.Add(item);
}
try
{
cmd.Connection.Open();
new SqlDataAdapter(cmd).Fill(ds);
}
catch (SqlException sqlex)
{
for (int i = 0; i < sqlex.Errors.Count; i++)
{
var sqlexDetail = String.Format("From ExecuteSQLReturnDataTable(), SQL Exception #{0}{1}Source: {2}{1}Number: {3}{1}State: {4}{1}Class: {5}{1}Server: {6}{1}Message: {7}{1}Procedure: {8}{1}LineNumber: {9}",
i + 1, // Some users would get the fantods if they saw #0
Environment.NewLine,
sqlex.Errors[i].Source,
sqlex.Errors[i].Number,
sqlex.Errors[i].State,
sqlex.Errors[i].Class,
sqlex.Errors[i].Server,
sqlex.Errors[i].Message,
sqlex.Errors[i].Procedure,
sqlex.Errors[i].LineNumber);
MessageBox.Show(sqlexDetail);
}
}
catch (Exception ex)
{
String exDetail = String.Format(PriceComplianceConstsAndUtils.ExceptionFormatString, ex.Message, Environment.NewLine, ex.Source, ex.StackTrace);
MessageBox.Show(exDetail);
}
return ds.Tables[0];
}
}
ストアド プロシージャの最初の部分は次のとおりです。
ALTER procedure [dbo].[sp_duckbilled_platypus]
@BegDate varchar(10),
@EndDate varchar(10),
@Member varchar(max),
@Unit varchar(max)
AS
drop table zDistDBPExceptions
select (ph.memberno), TotalDesExceptions=1
into zDistDBPExceptions
from priceexceptionshistory ph
inner join MasterUnits MU on ph.Unit=MU.Unit
Inner Join Members M on ph.memberno = M.MemberNo
where ph.memberNo not in ('04501','04503') --,'111','B140')
and ph.memberno in (select [value] from dbo.split(@member,','))
and ph.Unit in (select [value] from dbo.Split(@Unit,','))
and invoicedate between @BegDate and @EndDate
and filtered=0
and abs(contractprice) = 0
and abs(ph.pricepush) = 0
and bidprice > 0
and abs(MU.TruTrack) = 1
and abs(ph.pricesheet) = 1
drop table zContractDBPExceptions
select (ph.memberno), TotalContractExceptions=1
into zContractDBPExceptions
from priceexceptionshistory ph
inner join MasterUnits MU on ph.Unit=MU.Unit
Inner Join Members M on ph.memberno = M.MemberNo
where ph.memberNo not in ('04501','04503') --,'111','B140')
and ph.memberno in (select [value] from dbo.split(@member,','))
and ph.Unit in (select [value] from dbo.Split(@Unit,','))
and invoicedate between @BegDate and @EndDate
and filtered=0
and abs(contractprice) = 1
and abs(ph.pricepush) = 1
and bidprice > 0
and abs(MU.TruTrack) = 1
drop table zDBPExceptions
select (ph.memberno), TotalPriceSheetExceptions=1--, invoicedate
into zDBPExceptions
from priceexceptionshistory ph
inner join MasterUnits MU on ph.Unit=MU.Unit
Inner Join Members M on ph.memberno = M.MemberNo
where ph.memberNo not in ('04501','04503') --,'111','B140')
and ph.memberno in (select [value] from dbo.split(@member,','))
and ph.Unit in (select [value] from dbo.Split(@Unit,','))
and invoicedate between @BegDate and @EndDate
and filtered=0
and abs(contractprice) = 0
and abs(ph.pricepush) = 1
and bidprice > 0
and abs(MU.TruTrack) = 1
drop table zSumtDBPExceptions
select (ph.memberno), TotalSumExceptions=1
into zSumtDBPExceptions
from priceexceptionshistory ph
inner join MasterUnits MU on ph.Unit=MU.Unit
Inner Join Members M on ph.memberno = M.MemberNo
where ph.memberNo not in ('04501','04503') --,'111','B140')
and ph.memberno in (select [value] from dbo.split(@member,','))
and ph.Unit in (select [value] from dbo.Split(@Unit,','))
and invoicedate between @BegDate and @EndDate
and filtered=0
and bidprice > 0
and abs(MU.TruTrack) = 1
and abs(ph.pricesheet) = 1
--this gets all invoice data
--insert into PriceExceptionsHistory
-- *** zContractDBPBase ***
drop table zContractDBPBase
. . .
起こっている非常に奇妙な (ISTM) ことは、昨日、ストアド プロシージャがまったく実行に失敗し、削除されたテーブル (すべてがストアド プロシージャに削除され、それぞれが順番にリストされている) が存在しなかったか、存在したことを示しています。それらへの許可を持っていません。それらはすべて存在します。そのため、権限が問題のようでした。
しかし、今朝、コードやデータベースに変更を加えることなく、ストアド プロシージャは最初は権限の問題を訴えることなく実行されました (初回のみ)。
ただし、2 回目の実行では、zContractDBPBase テーブルに対する権限がないことを訴えました。私は今、前の 4 つを削除するためのアクセス許可を持っていると思いますが、これは許可していません...?!?
IOW、エラー メッセージ (「クエリがエラーで完了しました」の後) は次のようになりました。
メッセージ 3701、レベル 11、状態 5、プロシージャ sp_zDBP_pella、行 80
テーブル 'zContractDBPBase' が存在しないか権限がないため、削除できません。
...以前は同じメッセージでしたが、削除されたテーブルは 1 つだけではありませんでした。
では、なぜパーミッションは可変なのでしょうか? テーブルのリストを更新しましたが、("zContractDBPBase") へのアクセス許可を持っていないように見えるテーブルがまだ表示されます。Visual Studio IDE 内のサーバー エクスプローラーと LINQPad の両方で更新すると表示されます。
「私」がテーブルを削除できるようにストアド プロシージャを取得するには、(ストアド プロシージャ自体を変更する以外に) 何をする必要がありますか?