<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://www.dotnetzone.gr:443/cs/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>ADO.NET</title><link>https://www.dotnetzone.gr:443/cs/forums/78/ShowForum.aspx</link><description>Θέματα σχετικά με την προσπέλαση δεδομένων μέσω του ADO.NET και του System.Data namespace</description><dc:language>el</dc:language><generator>CommunityServer 2.1 SP3 (Build: 20423.1)</generator><item><title>Απ: audit trail</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/32527.aspx</link><pubDate>Sun, 03 Jun 2007 22:43:51 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:32527</guid><dc:creator>tsavos</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/32527.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=78&amp;PostID=32527</wfw:commentRss><description>Εναλλακτικοί τρόποι αντιμετώπισης των αλλαγών στον κύριο πίνακα : &lt;br&gt;1. Μπορείς για κάθε έκδοση του κυρίως πίνακα να έχεις και έναν mirror table. Φυσικά ανεβάζει εκθετικά το κόστος συντήρησης του όλου συστήματος,&lt;br&gt;2. Μπορείς στον mirror πίνακα να έχεις column VersionID, και να αλλάζει τα sql statements ανάλογα με το versionID. Αν σε ενδιαφέρει η οικονομία χώρου είναι καλή λύση.&lt;br&gt;&lt;br&gt;Πολύ σημαντική παράμετρος - που ξέχασα να αναφέρω - για την σχεδίαση της λύσης του audit είναι για πόσο διάστημα θα πρέπει να συντηρούνται τα αρχεία audit, αν πρέπει να κρατιούνται on-line ή και off-line και φυσικά τι αναμενόμενο μέγεθος αρχείου θα προκύψει για το διάστημα διατήρησης των αρχείων.&lt;br&gt;&lt;br&gt;</description></item><item><title>Απ: audit trail</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/32488.aspx</link><pubDate>Sat, 02 Jun 2007 09:13:43 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:32488</guid><dc:creator>Παναγιώτης Καναβός</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/32488.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=78&amp;PostID=32488</wfw:commentRss><description>&lt;P&gt;Η λύση αυτή είναι καλή αν έχεις μικρό αριθμό πινάκων, ή αν δημιουργείς το script των πινάκων μέσω generator, οπότε μπορείς εύκολα να δημιουργήσεις τους mirror πίνακες. Έχει όμως πρόβλημα αν αλλάξουν οι πίνακες, καθώς κάποια πληροφορία θα χαθεί. Ακόμα και αν πεις ότι μόνο προσθέτεις πεδία στους mirror, τα νέα πεδία θα περιέχουν NULL τιμές για τις παλιές εγγραφές, τις οποίες δεν θα μπορείς να ξεχωρίσεις από πραγματικές NULL. &lt;/P&gt;
&lt;P&gt;Αυτό είναι ένα διαφορετικό ζήτημα με τα audits, το οποίο δεν αφορά μόνο τα mirror tables. Δεν αρκεί δηλαδή να αποθηκεύεις μόνο τα δεδομένα στο audit trail. Για να μπορέσεις να τα ξαναδιαβάσεις, κάπου θα πρέπει να κρατάς και το σχήμα τους. Στην περίπτωση που τα αποθηκεύεις σαν XML, π.χ. αν αποθηκεύσεις το DataSet σαν DiffGram με την WriteXML, έχεις και το σχήμα, και τις τροποποιημένες τιμες. Το κάθε audit record όμως θα βγει αρκετά μεγαλύτερο.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description></item><item><title>Απ: audit trail</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/32486.aspx</link><pubDate>Sat, 02 Jun 2007 08:46:22 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:32486</guid><dc:creator>tsavos</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/32486.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=78&amp;PostID=32486</wfw:commentRss><description>Συγνώμη μαλλον δεν το διατύπωσα καλά αλλά εννοούσα ακριβως να δημιουργήσεις 2ο πινακα mirror.&lt;br&gt;Σε αυτόν θα κάνεις και το join με τον πίνακα χρηστών για να δεις ποιός έκανε τι και πότε.&lt;br&gt;Η λύση αυτή είναι απλή αλλά δεν είναι πλήρης. Δεν έχεις καμία πληροφορία για το π.χ. τι εκθέσεις τύπωσε ο χρήστης, ή τι εγγραφές διάβασε. Έχεις πληροφορία μόνο για ότι πρόσθεσε ή ενημέρωσε.&lt;br&gt;&lt;br&gt;</description></item><item><title>Απ: audit trail</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/32466.aspx</link><pubDate>Sat, 02 Jun 2007 02:38:02 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:32466</guid><dc:creator>Παναγιώτης Καναβός</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/32466.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=78&amp;PostID=32466</wfw:commentRss><description>&lt;P&gt;Τα πάντα εξαρτώνται από το τί θέλεις να κρατήσεις. Ο λόγος που δεν έδωσα βαρύτητα στη χρήση trigger στη βάση είναι ότι η πληροφορία που καταγράφουν δεν είναι ιδιαίτερα χρήσιμη αν ένας admin θέλει να δει τί έγινε. Αν κρατάς απλά τα πεδία δημιουργίας και τελευταίας αλλαγής του πίνακα, ουσιαστικά δεν έχεις audit trail. Αν θέλεις να κρατήσεις κάθε αλλαγή που γίνεται θα πρέπει ουσιαστικά να κάνεις mirror τον κάθε πίνακα που χρειάζεται να κάνεις audit προκειμένου να κρατήσεις τα τροποποιημένα πεδία. Μία πιθανή αντιμετώπιση βέβαια θα ήταν στα triggers&amp;nbsp;να μαζεύεις όλες τις αλλαγμένες τιμές σε ένα XML και να το γράφεις στον&amp;nbsp;audit πίνακα. &lt;/P&gt;
&lt;P&gt;Με το auditing σε επίπεδο βάσης όμως χάνεις την πληροφορία του τί πήγε να κάνει ο χρήστης καθώς και του ποιές τροποποιήσεις έγιναν ως αποτέλεσμα μίας ενέργειας του χρήστη. Για παράδειγμα, η δημιουργία μίας παραγγελίας μπορεί να προκαλέσει αλλαγές σε πολλούς audited πίνακες. Χρησιμοποιώντας μόνο triggers δεν είναι δυνατόν να δει κανείς ποιές αλλαγές οφείλονται σε μία και μόνο ενέργεια. Επίσης, χάνεις τη δυνατότητα ενεργειών που δεν αφορούν πίνακες, π.χ. πότε έκανε login ο χρήστης.&lt;/P&gt;
&lt;P&gt;Σε περίπτωση που χρησιμοποιούνται stored procedures οι καταχωρήσεις στον audit πίνακα μπορούν να γίνονται μέσα σε κάθε stored procedure. Έτσι μπορεί κανείς να έχει την επιπλέον πληροφορία που χρειάζεται, αν και είναι φασαρία να γραφτούν.&lt;/P&gt;
&lt;P&gt;Το σημαντικό είναι να αποφασίσει κανείς τί θέλει να κάνει με το audit trail.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Τα created, updated πεδία είναι καλά όταν θέλεις να ξέρεις ποιός έκανε την τελευταία αλλαγή, δεν σου λένε όμως ποιά είναι αυτή. Υπερεπαρκές για εφαρμογές με μικρές απαιτήσεις ασφάλειας.&lt;/LI&gt;
&lt;LI&gt;Ο audit πίνακας με XML data και triggers ή stored proceduresσου το λέει, δεν σου λέει όμως τί πήγε να κάνει ο χρήστης, ή τί άλλο έκανε ο χρήστης σε εκείνο το session.&amp;nbsp;Αυτό ίσως να μπορείς να το βρεις συνδυάζοντας άλλα logs.&lt;/LI&gt;
&lt;LI&gt;Το auditing από την ίδια την εφαρμογή σου λέει ακριβώς τί έκανε ο χρήστης, θέλει όμως την κατάλληλη σχεδίαση.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description></item><item><title>Απ: audit trail</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/32464.aspx</link><pubDate>Sat, 02 Jun 2007 01:50:47 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:32464</guid><dc:creator>tsavos</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/32464.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=78&amp;PostID=32464</wfw:commentRss><description>Μια άλλη προσέγγιση είναι με triggers στην ΒΔ. &lt;br&gt;Έτσι κρατάς audit trail σε επίπεδο πίνακα. &lt;br&gt;Στον πίνακα που θα κάνεις audit όπως και στον πίνακα με το audit trail θα έχεις κάποια πεδία του στύλ:&lt;br&gt;- Created By&lt;br&gt;- Updated By &lt;br&gt;- Created At&lt;br&gt;- Updated At&lt;br&gt;&lt;br&gt;Μετά μπορείς να κάνεις ένα join τον πίνακα με το audit trail με τον πίνακα των χρηστών και δεις ποιός έκανε τι και πότε, σε επίπεδο πίνακα ΒΔ πάντα. &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;</description></item><item><title>Απ: audit trail</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/32460.aspx</link><pubDate>Sat, 02 Jun 2007 01:26:54 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:32460</guid><dc:creator>Παναγιώτης Καναβός</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/32460.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=78&amp;PostID=32460</wfw:commentRss><description>&lt;P&gt;Θα πρέπει πρώτα να σκεφτείς τί θα το κάνεις αυτό το audit trail. Όπως λέει και ο Kelman, πρώτα σχεδίασε τί θέλεις να κάνεις και μετά σκέψου πως θα το υλοποιήσεις. &lt;/P&gt;
&lt;P&gt;Συνήθως, τα audit trails υπάρχουν για να διαβάζονται από κάποιον admin. Άλλοτε, υπάρχουν για να εκτυπώνονται αναφορές για έλεγχο στο τέλος της ημέρας. Άλλες φορές, υπάρχουν για να ικανοποιείται ο πελάτης ότι υπάρχει και αυτό. &lt;/P&gt;
&lt;P&gt;Για τη&amp;nbsp;τρίτη περίπτωση αρκεί να γράψεις βρεις κάπως τα δεδομένα που άλλαξαν και να τα γράψεις κάπου. Όταν όμως πάει κάποιος να χρησιμοποιήσει το audit trail θα τα βρει μπαστούνια, καθώς θα βλέπει μεν ποιά είναι τα δεδομένα που άλλαξαν, αλλά δεν θα ξέρει το γιατί. Σε αυτή την περίπτωση μπορείς άνετα να πάρεις τις αλλαγές με την GetChanges και να τις κάνεις serialize σε ένα XML. &lt;/P&gt;
&lt;P&gt;Για την πρώτη περίπτωση, θα πρέπει να καταχωρήσεις επιπλέον πληροφορίες, όπως το τί έκανε ο χρήστης, π.χ. "Δημιουργία χρήστη", και τα δεδομένα με μορφή που να έχει νόημα, π.χ. username, roles assigned κλπ. Δεν αρκεί απλά να βάλεις τις τιμές, πρέπει να έχουν μία μορφή που να έχει νόημα για τον admin.&amp;nbsp;Επίσης, θα πρέπει να βάλεις και τις ΠΡΙΝ και τις ΜΕΤΑ τιμές, για να μπορεί να καταλάβει ο admin τί έγινε. Σε μεγάλο βαθμό βέβαια μπορείς την ωραία παρουσίαση να την κάνεις σε ένα audit viewer ή σε ένα audit report.&lt;BR&gt;Τέλος, καλό είναι να αποθηκεύεις και κάποιο SessionID για να μπορούν να συνδεθούν οι ενέργειες ενός χρήστη μεταξύ τους.&lt;/P&gt;
&lt;P&gt;Κάτι άλλο που πρέπει να σκεφτείς, είναι που θα γίνει το auditing. Αν γίνεται στον client μπορεί κάποιος χρήστης να χτυπήσει τη βάση απευθείας με ένα query editor και να πειράξει τους πίνακες. Σε αυτή την περίπτωση θα πρέπει να υλοποιηθεί το auditing μέσω triggers, κάτι που είναι ολίγον μπελάς. Αν μεσολαβούν server components (COM+, Enterprise Service, Remoting ή WCF) μπορείς να κάνεις το audit σε αυτά και να επιτρέψεις την πρόσβαση στη βάση μόνο μέσω αυτών. &lt;/P&gt;
&lt;P&gt;Επίσης θα πρέπει να σκεφτείς τί θα κάνεις audit. Το καλύτερο είναι να κάνεις audit τα business actions, όπως στο παράδειγμα του χρήστη, και όχι τις επιμέρους αλλαγές που έκανε η εφαρμογή. Ο πιο ευέλικτος τρόπος να κάνεις audit είναι στα server components να καταγράφεις την ενέργεια και τις παραμέτρους της. Αν π.χ. έχεις ένα component UserManager, όταν ολοκληρωθεί η κλήση της CreateUser και πριν κάνεις commit το transaction, κάνεις και την καταγραφή στο audit trail. &lt;/P&gt;
&lt;P&gt;Αν υποθέσουμε ότι δεν έχεις server components μία καλή τακτική θα ήταν να αποθηκεύεις την ενέργεια (π.χ. διαγραφή χρήστη), χρόνο κλπ., τις παραμέτρους&amp;nbsp;και σε μοργή XML το τροποποιημένο Dataset, απλά και μόνο σαν reference. &lt;BR&gt;&lt;/P&gt;
&lt;P&gt;Ακόμα καλύτερο όμως θα ήταν να χρησιμοποιήσεις το Logging Application Block του Enterprise Library. Μαζεύει μόνο του τα περισσότερα στοιχεία (π.χ. ώρα, μηχάνημα, session ID, IP κλπ), μπορεί να αποθηκεύσει τα δεδομένα σε πολλές μορφές (αρχείο, βάση, ακόμα και email στέλνει) και το μόνο που καλείς στο τέλος είναι ένα ... &lt;SPAN style="FONT-WEIGHT:normal;FONT-SIZE:11px;COLOR:black;FONT-FAMILY:Courier New;BACKGROUND-COLOR:transparent;"&gt;Logger.WriteEntry()&lt;BR&gt;&lt;/SPAN&gt;Σε αυτό μπορείς να καταχωρήσεις ένα επεξηγηματικό κείμενο, κατηγορία, event κλπ και επιπλέον δεδομένα (π.χ. παραμέτρους της ενέργειας) σαν dictionary. Την σωστή αποθήκευση τους την αναλαμβάνει η βιβλιοθήκη. Μπορείς μάλιστα να ορίσεις ότι οι παράμετροι θα αποθηκεύονται ακόμα και στη βάση ως XML και μετά να κάνεις query σε αυτό το XML για να φτιάξεις τα report που θέλεις. &lt;/P&gt;
&lt;P&gt;Προσωπικά έχω χρησιμοποιήσει το Logging Block με αυτό ακριβώς τον τρόπο, για να καταγράφω εισερχόμενες εντολές από άλλα συστήματα. Κάθε φορά που ερχόταν ένα μήνυμα έκανα μία εγγραφή κατά την εκκίνηση και τη λήξη της επεξεργασίας αποθηκεύοντας τα περιεχόμενα της εντολής στο dictionary. Μετά ρύθμισα το logging να γίνεται και σε αρχείο και στη βάση με το dictionary να αποθηκεύεται σε XML. Έτσι μπορούσα να κάνω queries για να δω πόσες εντολές πέτυχαν ή απέτυχαν ανά ημέρα, κλπ.&lt;/P&gt;</description></item><item><title>audit trail</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/32456.aspx</link><pubDate>Sat, 02 Jun 2007 00:39:31 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:32456</guid><dc:creator>nettraptor1</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/32456.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=78&amp;PostID=32456</wfw:commentRss><description>Καλησπέρα.&lt;br&gt;&lt;br&gt;σε μία vb.net εφαρμογή χρησιμοποιώ ενα windows.forms.datagrid&amp;nbsp; όπου ο χρήστης μέτα τις όποιες αλλαγές που θα κάνει θα αποθηκευοντε ώς εξής&lt;br&gt;&lt;br&gt;&amp;nbsp;If m_DataSet_TYPES.HasChanges() Then&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; DO&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;  .....&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;  ....&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; .....&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; data_adapter.Update(m_DataSet_TYPES)&lt;br&gt;end if&lt;br&gt;&lt;br&gt;Το πρόβλημά μου όμως ειναι το πώς θα βρώ ενα τρόπο ώστε να κρατάω σε ενα table AUDIT τις αλλαγες που έγιναν και απο ποιον.&lt;br&gt;στην προσπάθεια μου βρήκα ενα τρόπο παίρνοντας τις αλλαγές απο to xdataset ας πούμε και βάζοντας τις αλλαγές μέσα στο πίνακα audit..&lt;br&gt;xDataSet = m_DataSet_TYPES.GetChanges(DataRowState.Modified)&lt;br&gt;&lt;br&gt;Θα μπορούσατε να μου πείτε ενα λογικό τρόπο.. &lt;br&gt;Ευχαριστώ..&lt;br&gt;&lt;br&gt;&lt;br&gt;</description></item></channel></rss>