#c# #sql #sql-server #stored-procedures
#c# #sql #хранимые процедуры #массивы
Вопрос:
Прежде всего, я все перепробовал и не могу понять, почему он не обновит мое поле varbinary должным образом.
из 1728 байт в поле сохраняется только последний байт в массиве байтов…
Я генерирую свой байтовый массив следующим образом:
public static byte[] StringToByteArray(String hex)
{
int NumberChars = hex.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i = 2)
bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
return bytes;
}
Я также попробовал приведенный ниже:
public static byte[] ParseHex(string hex)
{
int offset = hex.StartsWith("0x") ? 2 : 0;
if ((hex.Length % 2) != 0)
{
throw new ArgumentException("Invalid length: " hex.Length);
}
byte[] ret = new byte[(hex.Length - offset) / 2];
for (int i = 0; i < ret.Length; i )
{
ret[i] = (byte)((ParseNybble(hex[offset]) << 4)
| ParseNybble(hex[offset 1]));
offset = 2;
}
return ret;
}
static int ParseNybble(char c)
{
if (c >= '0' amp;amp; c <= '9')
{
return c - '0';
}
if (c >= 'A' amp;amp; c <= 'F')
{
return c - 'A' 10;
}
if (c >= 'a' amp;amp; c <= 'f')
{
return c - 'a' 10;
}
throw new ArgumentException("Invalid hex digit: " c);
}
Мой код на c # для сохранения данных таков:
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["DB_Conn"].ConnectionString))
{
byte[] to_store = StringToByteArray(inventory);
//State the Stored Proc and add Values to 'cmd' to pass to the Stored Proc
SqlCommand cmd = new SqlCommand("_USP_store", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@A", TB_A.Text);
cmd.Parameters.Add("@B", SqlDbType.VarBinary, 1728).Value = to_store;
try
{
// Open Connection and execute Stored Proc
conn.Open();
cmd.ExecuteNonQuery();
C2_Wipe_Message.Text = "Storing success";
C2_Wipe_Message.ForeColor = Color.FromArgb(0, 0, 255, 0);
}
catch
{
C2_Wipe_Message.Text = "An error occured..";
C2_Wipe_Message.ForeColor = Color.FromArgb(0, 255, 0, 0);
}
finally
{
if (conn.State == System.Data.ConnectionState.Open)
{
//Close connection IF open
conn.Close();
}
}
}
Я отправил его в виде строки, я отправил его в виде простого двоичного файла, я отправил его в виде массива шестнадцатеричных байтов и т.д.
Я предполагаю использовать цикл while в sql для его хранения, но это не объясняет, почему последний байт всегда сохраняется вместо первого байта массива байтов, пожалуйста, просветите меня, потому что это бесит..
* SQL SP
@A varchar(10),
@B varbinary(1728)
AS
UPDATE Invenotry
SET A = @B
WHERE (Name = @A)
Комментарии:
1. Давайте посмотрим на SQL, я ожидаю, что проблема существует, поскольку использование цикла в SQL звучит для меня неправильно.
2. не используя цикл, но я получу процедуру sql
3. Каков тип поля
[Invenotry].[A]
?4. Это поле varchar(10), оно содержит имя. приложение должно иметь поля, для простоты поля A и поля B, поле A содержит имя, поле B содержит удобочитаемый вывод / ввод массива шестнадцатеричных байтов.
5. Смотрите Ответ ниже на основе таблицы, содержащей поля A и B. Если это не так, пожалуйста, опубликуйте определение таблицы для
Invenotry
Ответ №1:
Ваш sql должен быть таким:
UPDATE Invenotry
SET B = @B
WHERE A = @A
Вы также можете попробовать полную версию конструктора параметров:
SqlParamter param = new SqlParameter("@B", SqlDbType.VarBinary, 1728, ParameterDirection.Input,
// we have these parameters but they are ignored for input types
false, 0, 0, null, DataRowVersion.Current,
// the data
to_store);
cmd.Parameters.Add(param);
Комментарии:
1. тестируя это сейчас, побочный вопрос: какой способ преобразования шестнадцатеричной строки в байтовый массив вы бы использовали из двух описанных выше способов? или вы бы использовали другой метод в целом?
2. похоже, ему не понравились ‘(‘ и ‘)’ вокруг предложения WHERE, однако я заметил, что моей самой большой проблемой было присвоение полям правильного имени. Теперь я соответствующим образом изменил имена полей, а также присвоил надлежащий размер переменному полю (это было 1726 вместо 1728 ..) Хотя мне все еще интересно, какое преобразование в байтовый массив вы бы порекомендовали
3. Первый кажется более простым, однако он не проверяет начало
0x
— ожидаете ли вы увидеть начало0x
?4. Я ожидаю, что все, что лучше всего работает с полем базы данных, имеет наименьшие накладные расходы.
5. Я думаю, цель состоит в том, чтобы оба они возвращали одно и то же — я ожидаю, что внутренняя библиотека будет быстрее, но лучший способ узнать это — протестировать оба.