Aymane HATAFI Ответов: 3

Sql SERVER 2012 select from column не зная имени этого последнего столбца


Пожалуйста, прочтите до конца
Привет всем я новичок на этом ado.net и я хочу принести данные,чтобы показать их на моем представлении сетки данных, поэтому у меня есть две таблицы, структура первой таблицы, включая значения :
idrubrique namerubrique

1 зарплата
2 транс
3 панир
4 Конге

а структура второй таблицы такова,включая значения :
idemployee зарплата сотрудника trans panier congé
1 Фалес 125 25 24 62
2 интерим 254 87 12 34
3 Аймане 524 25 45 47


к которому я хочу, чтобы он был показан на виде сетки Dat, это так
idemployee сотрудник namerubrique montant
1 зарплата Фалеса 125
1 Фалес транс 25
1 Фалес панье 24
1 thales congé 62 ,то же самое для всех сотрудников.
причина, по которой я не вставляю это в одну таблицу с самого начала, заключается в том, что namerubrique может измениться в любой ручной причине, введенной пользователем приложения.
Надеюсь, вы меня понимаете.
вы можете помочь синтаксисом в sql server, а затем я буду использовать его в c#
в приведенном ниже коде, который я попробовал, вы найдете те же имена других таблиц и столбцов, которые они не имели значения.
Заранее спасибо.

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

string nomrubrique = string.Empty;
            int count;
            DataTable dt2 = new DataTable();
            dt2.Clear();
            cnx.Open();
            {
                SqlCommand cmd = new SqlCommand("select nomrubrique from rubrique", cnx);
                SqlDataReader dr = cmd.ExecuteReader();
                DataTable dt = new DataTable();
                dt.Load(dr);
                SqlCommand cmd1 = new SqlCommand("select * from paie where  paie.nomclient='" + comboBox1.SelectedValue + "'", cnx);
                SqlDataReader dr1 = cmd1.ExecuteReader();
                DataTable dt1 = new DataTable();
                dt1.Load(dr1);
                {
                    SqlCommand cmd4 = new SqlCommand("select count (*) from rubrique",cnx);
                    cmd4.ExecuteNonQuery();
                    count =(int) cmd4.ExecuteScalar();
                    for (int i=1;i<count;i++)
                    {
                        SqlCommand cmd3 = new SqlCommand("select nomrubrique from rubrique WHERE numrubrique="+i+"",cnx);
                        cmd3.ExecuteNonQuery();
                        nomrubrique = (string)cmd3.ExecuteScalar();
                        foreach (DataRow row in dt.Rows)
                        {
                            foreach (DataRow row1 in dt1.Rows)
                            {
                                SqlCommand cmd2 = new SqlCommand("select distinct client.nomclient,adresse,ice,matricule,nomemp,prenomemp,nomrubrique," + row1[nomrubrique] + " as coef," + row1[nomrubrique] + " * coef as total from paie join client on paie.nomclient=client.nomclient join contrat on client.codeclient=contrat.codeclient join rubrique on contrat.numrubrique=rubrique.numrubrique where client.nomclient='" + comboBox1.SelectedValue + "' and paie.nomclient='" + comboBox1.SelectedValue + "' and nomrubrique='" + row[nomrubrique] + "'", cnx);
                                SqlDataReader dr2 = cmd2.ExecuteReader();

                                dt2.Load(dr2);

                            }
                        }
                    }
                }
            }
            dataGridView1.DataSource = dt2;
            cnx.Close();

Tomas Takac

Во-первых, у вас не так много запросов. Вы трижды запрашиваете таблицу rubrique, чтобы получить nomrubrique, затем граф, затем снова nomrubrique. В этом нет необходимости.

Во-вторых, вы должны хранить свои данные по-другому. Оставь себе свою таблицу рубрик. Удалите столбцы зарплата, транс, панье, Конге из таблицы сотрудников. Создайте новую таблицу rubrique_employe со столбцами idemployee, idrubrique, montant. Это должно решить ваши проблемы.

Aymane HATAFI

вторая таблица включающая столбцы зарплата и panier и trans а также congé является статической потому что она будет импортирована из файла excel так что у меня нет разрешения на ее изменение

3 Ответов

Рейтинг:
1

an0ther1

Чтобы получить нужную вам структуру, вам нужно будет использовать UNION - refer; СОЮЗ (Transact-SQL)[^]

Ваша сделка будет выглядеть следующим образом;

SELECT idemployee, employee, 'salary' AS namerubrique, salary
FROM Employee
UNION
SELECT idemployee, employee, 'trans' AS namerubrique, trans
FROM Employee
UNION
SELECT idemployee, employee, 'panier' AS namerubrique, panier
FROM Employee
UNION
SELECT idemployee, employee, 'congé' AS namerubrique, congé 
FROM Employee


Примечание: Если вы хотите упорядочить столбцы, добавьте оператор Order By после последнего оператора SELECT

с уважением


Aymane HATAFI

Спасибо большое бро, что работа для меня, но я думаю, что это будет работать только на этом потому что когда пользователь будет вводить новый namerubrique это не работает, поэтому мне нужно что-то вроде или что-то подобное, который будет показывать все namerubrique существующие на стол rubrique

an0ther1

Оба решения Maciej &my имеют одну и ту же проблему, но ни одно из них не зависит от значения столбца idrubrique.
Когда пользователь добавляет новый namerubrique, как создается новый столбец в таблице Employee?

Maciej Los

Союз? Я бы предпочел использовать UNPIVOT в этом случае. Смотрите мой ответ.

an0ther1

Справедливый вызов Мацей - получил свой ответ. Хорошее решение

Maciej Los

Спасибо.

Рейтинг:
1

GenJerDan

Лично я бы создал представление на SQL-сервере, а затем запросил и отобразил данные из него, вместо того чтобы пытаться сопоставлять вещи на лету в коде.


Aymane HATAFI

я могу создать представление, оптимизированное методом "спасибо за эту информацию", но это не решит проблему

Рейтинг:
0

Maciej Los

Все, что вам нужно, это использовать оператор UNPIVOT[^]. Видеть:


DECLARE @second TABLE(idemployee INT IDENTITY(1,1), employee NVARCHAR(30), salary INT, trans INT, panier INT, congé INT)
INSERT INTO @second (employee, salary, trans, panier, congé)
VALUES('thales', 125, 25, 24, 62), 
('interime', 254, 87, 12, 34), 
('aymane', 524, 25, 45, 47)

SELECT idemployee, employee, namerubrique, montant
FROM @second  AS pvt
UNPIVOT (montant FOR namerubrique IN ([salary], [trans], [panier], [congé])) AS unpvt 


DataTable second = new DataTable();
second.Columns.AddRange(new DataColumn[]
	{new DataColumn("idemployee", typeof(int)),
	new DataColumn("employee", typeof(string)),
	new DataColumn("salary", typeof(int)),
	new DataColumn("trans", typeof(int)),
	new DataColumn("panier", typeof(int)),
	new DataColumn("congé", typeof(int))});
second.Rows.Add(new object[]{1, "thales", 125, 25, 24, 62}); 
second.Rows.Add(new object[]{2, "interime", 254, 87, 12, 34});  
second.Rows.Add(new object[]{3, "aymane", 524, 25, 45, 47}); 

string[] cols = new string[]{"salary","trans", "panier", "congé"};

var unpivot = second.AsEnumerable()
	.SelectMany(x=> cols.Select(c=> new
		{
			idemployee = x.Field<int>("idemployee"),
			employee = x.Field<string>("employee"),
			namerubrique = c,
			montant = x[c]
		}));



В обоих случаях результат один и тот же:
idemployee	employee	namerubrique	montant
1			thales		salary			125
1			thales		trans			25
1			thales		panier			24
1			thales		congé			62
2			interime	salary			254
2			interime	trans			87
2			interime	panier			12
2			interime	congé			34
3			aymane		salary			524
3			aymane		trans			25
3			aymane		panier			45
3			aymane		congé			47


Бог удачи!


Кстати: Ваш код таков SQL-инъекция[^] уязвимый!
Вы должны избегать использования конкатенированной строки в качестве запроса(ов)!
Как: защита от SQL-инъекций в ASP.NET[^]
Написание безопасного динамического SQL в SQL Server | Microsoft Docs[^]