harristars Ответов: 3

Как сгенерировать идентификатор продукта, содержащий буквы и цифры на языке Си#


Как я могу создать строку кода в c#, которую я буду использовать для предоставления каждого нового продукта, добавляемого в мою таблицу продуктов?Я использую базу данных MySQL.Первые две должны быть буквой, за которой следует цифра и обратная косая черта, а затем слово POS. например, PC01/POS.
Это то, что я пробовал до сих пор, хотя это не то, что мне действительно нужно.

Что я уже пробовал:

//auto product number
static string IncrementID(string startValue, int numNonDigits)
{
    string nonDigits = startValue.Substring(0, numNonDigits);
    int len = startValue.Length - numNonDigits;
    int number = int.Parse(startValue.Substring(numNonDigits));
    number++;
    if (number >= Math.Pow(10, len)) number = 1; // start again at 1
    return String.Format("{0}{1:D" + len.ToString() + "}", nonDigits, number);
}
private void Genarate_productcode()
{
    product_code.Text = IncrementID("QIEpl/PO/0000009", 9); // produces QIEpl/PO/0000010 // C00011 PCI0001
}  

phil.o

/ это косая черта. Обратная косая черта-это \ :)

3 Ответов

Рейтинг:
20

CHill60

Я лично не стал бы генерировать идентификатор в коде C#, я бы использовал базу данных MySQL для генерации идентификатора для меня: см. MySQL :: MySQL 5.7 справочное руководство :: 3.6.9 использование AUTO_INCREMENT[^]

Я, конечно же, никогда не буду использовать метод, который полагается на мое увеличение "предыдущего" числа, поскольку он не будет работать в многопользовательской среде.

Как только у вас есть этот числовой идентификатор, вы можете отобразить его так, как хотите, например (не проверено!)

String.Format("PC{0}//POS", id.ToString(D2));
хотя я бы также не ограничил свой выход от 1 до 99 .. используйте по крайней мере D5.

Если вы действительно хотите сохранить текстовую версию в базе данных, то можете использовать триггер (MySQL: после вставки триггера[^]) для захвата идентификатора и генерации текстовой версии

[Редактировать после ОП комментарий]
Попробуйте что-то вроде следующего (обратите внимание еще раз, непроверенное!)
CREATE TRIGGER product_id
 AFTER INSERT
 ON test FOR EACH ROW
 	UPDATE test set textid = concat('PC', LPAD(NEW.id, 5, '0'), '/POS') WHERE id=NEW.id;
Объяснение:
Триггер называется product_id и он срабатывает после того, как строка или строки вставлены в таблицу test
В триггере есть только один оператор, поэтому я его не использовал BEGIN ... END, но вы уже продемонстрировали, что знаете, как это сделать с вашим кодом в комментариях - я просто ленив (и демонстрирую точку зрения). (Обратите внимание, что если у вас есть несколько операторов, вам нужно будет изменить разделитель при создании триггера - см. документацию)
Спусковой крючок собирается UPDATE стол test с помощью NEW.id. В специальной таблице NEW содержит... новая строка. Вы не можете обновить его. Есть еще одна специальная таблица OLD который также содержит старые значения.

Мне очень жаль, что я не смог проверить это должным образом, и это не то место, чтобы обучать вас дальше, но, по крайней мере, теперь у вас есть некоторые поисковые запросы, которые помогут вам в дальнейших исследованиях.

[EDIT - дополнительные примеры кода после комментариев OP. Это решение скрыто в пачках комментариев ниже].
И то и другое будет работать
DELIMITER //

CREATE TRIGGER product_id
 AFTER INSERT
 ON test 
 BEGIN
      String.Format("PC{0}//POS", id.ToString(D2));
 END; //
DELIMITER ;
или
CREATE TRIGGER product_id
 AFTER INSERT
 ON test 
      String.Format("PC{0}//POS", id.ToString(D2));

В частности, если вы хотите включить BEGIN и END вы должны использовать DELIMITER как хорошо!


harristars

позволь мне тоже попробовать

Maciej Los

Полностью согласен!
5ed!

harristars

я пытался, но не смог этого сделать .я изучил ссылку плюс код, который вы предоставляете..но где именно я должен разместить триггер MYSQL в коде

CHill60

Посмотрите на ссылку, триггеры идут в базу данных, а не в код

harristars

я действительно нахожусь в базе данных.я знаю, как установить автоматическое приращение, но это то, где я предполагаю, что мой product_id выглядит так, как этот PC01/POS. я не могу

harristars

я использую xampp для базы данных MySQL

harristars

в триггере я должен установить Определитель или определение после выбора таблицы .или как я могу его установить

harristars

объясните мне на примере пожалуйста

CHill60

В данный момент у меня нет доступа ни к sql, ни к mysql. Есть несколько примеров создания триггеров в этой документации или поиска "примеров триггеров mysql".
Что касается форматирования, то вам понадобится что-то вроде

UPDATE table set textid = concat('PC', LPAD(autoid, 5, '0'), '/POS');
- непроверенный.
Опять же - такого рода вещи действительно принадлежат слою пользовательского интерфейса, а не вашей базе данных

harristars

и все же я не могу этого понять .я искал различные примеры написания триггера, но все равно мой не работает

CHill60

Покажите код, который не работает ... или воспользуйтесь моим советом и сделайте форматирование в слое пользовательского интерфейса

harristars

Создать триггер product_id
ПОСЛЕ ВСТАВКИ
на испытаниях

НАЧАТЬ

-- декларации переменных

-- триггерный код
Строка.Формат("PC{0}//POS", id.ToString(D2));

КОНЕЦ;


я никогда не писал триггер mysql и готов учиться с его помощью.

CHill60

Я обновил свое решение некоторыми вещами, которые могут помочь

harristars

Оооо я позволил себе попробовать еще раз и пройти через это

harristars

 One or more errors have occurred while processing your request:
The following query has failed: "CREATE DEFINER=`root`@`localhost` TRIGGER `product_code` AFTER INSERT ON `inventory_table` FOR EACH ROW CREATE TRIGGER product_code AFTER INSERT ON test FOR EACH ROW BEGIN UPDATE test set textid = concat('PC', LPAD(NEW.id, 5, '0'), '/POS') WHERE id=NEW.id; END"

MySQL said: #1303 - Can't create a TRIGGER from within another stored routine 

Приведенный выше код - это ошибка, которую я получаю, когда выполняю код для триггера

CHill60

Похоже, что вы не изменили разделитель - либо измените разделитель при создании триггера - есть примеры по ссылкам, которые я вам уже дал, - либо избавьтесь от ненужных BEGIN и END в вашем коде определения триггера

harristars

Я все еще в тупике .Я использую phpmyadmin.каждый раз, когда я пишу триггер, я получаю эту ошибку
Mysql сказал : #1303 -не удается создать триггер из другой хранимой подпрограммы

CHill60

Вы сняли начало и конец с вашего триггера?

harristars

Да и это не сработало.Я пробовал много раз, но все равно это дает мне Mysql сказал : #1303 -не могу создать триггер из другой сохраненной процедуры.Я хотел бы, чтобы вы могли дать мне пример, который работает, что было бы лучше

CHill60

Я проверил код, прежде чем опубликовать его, и он сработал для меня.
Опубликуйте код, который вы используете для создания триггера

harristars

Создать триггер product_id
ПОСЛЕ ВСТАВКИ
на испытаниях

НАЧАТЬ

-- декларации переменных

-- триггерный код
Строка.Формат("PC{0}//POS", id.ToString(D2));

КОНЕЦ;
приведенный выше код я пробовал несколько раз и он не работает

harristars

не могли бы вы показать мне код, который вы тестируете, и его работу

CHill60

Я спросил тебя, вынул ли ты начало и конец из своего триггерного творения, и ты сказал "Да"!
Я не знаю, как объяснить это яснее ... вы должны либо удалить BEGIN и END от вашего имени CREATE TRIGGER... (это всего лишь одна строка, они вам не нужны) Или вы должны изменить DELIMITER перед запуском программы CREATE TRIGGER code!

DELIMITER //

CREATE TRIGGER product_id
 AFTER INSERT
 ON test 
 BEGIN
      String.Format("PC{0}//POS", id.ToString(D2));
 END; //
DELIMITER ;

Рейтинг:
2

Maciej Los

В дополнение к решению 1 by CHill60[^] я бы настоятельно рекомендовал "создать" идентификатор продукта со строковым префиксом на стороне сервера MySQL. Видеть: Как сделать автоматический инкремент первичного ключа таблицы MySQL с некоторым префиксом - переполнение стека[^]


Рейтинг:
0

#realJSOP

Это дурацкий вопрос, но вот он:

public static string IncrementID2(string startValue, int numNonDigits)
{
    int max = 999999999;
    string[] parts = startValue.Split('/');
    // is it safe to assume that the third splitted string is the number you're looking for?
    int number;
    if (Int32.TryParse(parts[2], out number))
    {
        number++;
    }
    else
    {
        if the number doesn't parse correctly, set it to zero
        number = 0;
    }
    number = (number > max) ? 1 : number;
    return string.Format("PC{0:D9}/POS", number);
}


harristars

позвольте мне попробовать и посмотреть, будет ли это работать

#realJSOP

Конечно, это будет работать, если вы передадите ему ту же строку, что и исходному методу.

harristars

если число не разбирается правильно, установите его равным нулю
количество = 0;


на этой линии есть проблема

CHill60

Это комментарий в коде. Похоже, маркер комментария отсутствует, так и должно быть

//if the number doesn't parse correctly, set it to zero;

harristars

частный недействительными Genarate_productcode()
{
код изделия.Text = IncrementID2(" ", 9);

}
является ли это правильным способом вызова функции, генерирующей product_code

CHill60

Попробуйте и посмотрите, что получится!

harristars

я пробовал это не работает

harristars

@John Simmons я все еще застрял на этом коде..как я могу вызвать приведенный выше статический метод в вашем коде.