Retrieve Overwritten View SnowFlake - snowflake-cloud-data-platform

Problem: I have accidentally overwrite a view in SnowFlake using CREATE OR REPLACE VIEW.
Question: Is there anyway to retrieve the old view i.e. the SQL code?

You can use QUERY_HISTORY to find the previous DDL used to create the query.
You can filter results using QUERY_TYPE which will help to you to find quickly the right query type.

If you can't find it in the query history tab using QUERY_TYPE > CREATE, you can search for it over the previous 365 days in the query history. This previous post has the SQL to run:
View DDL history of CREATE VIEW statement in Snowflake
Note that this is a big query if your account has run lots of queries over the last year. You can modify it to reduce the scan if necessary if you know more information, such as the month of creation.
If you want a totally informal and lightweight way to version your objects, I wrote one for my internal use that I decided to share. It's a table and stored procedure. Call the stored procedure with the object type and three-part name, and it adds a version row to the table. If it finds a pervious version, it marks the old one obsolete as of the current_timestamp and increments the number of the new version by 1.
https://github.com/GregPavlik/SimpleVersioning/blob/main/install.sql

Related

Get audit history records of any entity record as per CRM view

I want to display all audit history data as per MS CRM format.
I have imported all records from AuditBase table from CRM to another Database server table.
I want this table records using SQL query in Dynamics CRM format (as per above image).
I have done so far
select
AB.CreatedOn as [Created On],SUB.FullName [Changed By],
Value as Event,ab.AttributeMask [Changed Field],
AB.changeData [Old Value],'' [New Value] from Auditbase AB
inner join StringMap SM on SM.AttributeValue=AB.Action and SM.AttributeName='action'
inner join SystemUserBase SUB on SUB.SystemUserId=AB.UserId
--inner join MetadataSchema.Attribute ar on ab.AttributeMask = ar.ColumnNumber
--INNER JOIN MetadataSchema.Entity en ON ar.EntityId = en.EntityId and en.ObjectTypeCode=AB.ObjectTypeCode
--inner join Contact C on C.ContactId=AB.ObjectId
where objectid='00000000-0000-0000-000-000000000000'
Order by AB.CreatedOn desc
My problem is AttributeMask is a comma separated value that i need to compare with MetadataSchema.Attribute table's columnnumber field. And how to get New value from that entity.
I have already checked this link : Sql query to get data from audit history for opportunity entity, but its not giving me the [New Value].
NOTE : I can not use "RetrieveRecordChangeHistoryResponse", because i need to show these data in external webpage from sql table(Not CRM database).
Well, basically Dynamics CRM does not create this Audit View (the way you see it in CRM) using SQL query, so if you succeed in doing it, Microsoft will probably buy it from you as it would be much faster than the way it's currently handled :)
But really - the way it works currently, SQL is used only for obtaining all relevant Audit view records (without any matching with attributes metadata or whatever) and then, all the parsing and matching with metadata is done in .NET application. The logic is quite complex and there are so many different cases to handle, that I believe that recreating this in SQL would require not just some simple "select" query, but in fact some really complex procedure (and still that might be not enough, because not everything in CRM is kept in database, some things are simply compiled into the libraries of application) and weeks or maybe even months for one person to accomplish (of course that's my opinion, maybe some T-SQL guru will prove me wrong).
So, I would do it differently - use RetrieveRecordChangeHistoryRequest (which was already mentioned in some answers) to get all the Audit Details (already parsed and ready to use) using some kind of .NET application (probably running periodically, or maybe triggered by a plugin in CRM etc.) and put them in some Database in user-friendly format. You can then consume this database with whatever external application you want.
Also I don't understand your comment:
I can not use "RetrieveRecordChangeHistoryResponse", because i need to
show these data in external webpage from sql table(Not CRM database)
What kind of application cannot call external service (you can create a custom service, don't have to use CRM service) to get some data, but can access external database? You should not read from the db directly, better approach would be to prepare a web service returning the audit you want (using CRM SDK under the hood) and calling this service by external application. Unless of course your external app is only capable of reading databases, not running any custom web services...
It is not possible to reconstruct a complete audit history from the AuditBase tables alone. For the current values you still need the tables that are being audited.
The queries you would need to construct are complex and writing them may be avoided in case the RetrieveRecordChangeHistoryRequest is a suitable option as well.
(See also How to get audit record details using FetchXML on SO.)
NOTE
This answer was submitted before the original question was extended stating that the RetrieveRecordChangeHistoryRequest cannot be used.
As I said in comments, Audit table will have old value & new value, but not current value. Current value will be pushed as new value when next update happens.
In your OP query, ab.AttributeMask will return comma "," separated values and AB.changeData will return tilde "~" separated values. Read more
I assume you are fine with "~" separated values as Old Value column, want to show current values of fields in New Value column. This is not going to work when multiple fields are enabled for audit. You have to split the Attribute mask field value into CRM fields from AttributeView using ColumnNumber & get the required result.
I would recommend the below reference blog to start with, once you get the expected result, you can pull the current field value using extra query either in SQL or using C# in front end. But you should concatenate again with "~" for values to maintain the format.
https://marcuscrast.wordpress.com/2012/01/14/dynamics-crm-2011-audit-report-in-ssrs/
Update:
From the above blog, you can tweak the SP query with your fields, then convert the last select statement to 'select into' to create a new table for your storage.
Modify the Stored procedure to fetch the delta based on last run. Configure the sql job & schedule to run every day or so, to populate the table.
Then select & display the data as the way you want. I did the same in PowerBI under 3 days.
Pros/Cons: Obviously this requirement is for reporting purpose. Globally reporting requirements will be mirroring database by replication or other means and won't be interrupting Prod users & Async server by injecting plugins or any On demand Adhoc service calls. Moreover you have access to database & not CRM online. Better not to reinvent the wheel & take forward the available solution. This is my humble opinion & based on a Microsoft internal project implementation.

How to perform cleaning operations on all tables in a database based on actions in a table

I am not sure how to word this, and it might be easy, but I have one table with a list of actions for several variables
Example of data:
Table=X
Variable=AccountNumber
Action=Set to blank (written in SQL code)
I want the code to go to X.accountnumber and perform action, and do this for all the table/variables combination in a particular database
I assume I will need dynamic SQL for this? I am just trying to figure out how to get started in doing a column by column search for each table and if the column matches, call the action from the action table
Any ideas?
I'd recommend using the undocumented stored procedure sp_msforeachtable.
See here for more info
Agree with #Jeffrey Van Laethem, more information here
sp_MSforeachtable

Adding a column to a table in SQLite

I've got a table in SQLite, and it already has many rows stored in it. I know realise I need another column in the table. Up to now I've just deleted the database and started again because the data has just been test data. But now the data in the database can't be deleted.
I know the query to add a column to the table, my question is what is a good way to do this so that it works for both existing users and new users? (I have updated the CREATE query I have for when the table is not found (because it's a new user or an existing user has cleared the database). It seems wrong to have an ALTER query in software that ships, and check every time. Is there some way of telling SQLite to automatically add the column if it doesn't exist during the UPDATE query I now need?
If I discover I need more columns in the future, is having a bunch of ALTER statements on startup (or somewhere?) really the best way to do it?
(If relevant this is for a node js app)
I'd just throw a table somewhere that marks what version of your database it is, and check that to determine if an update is needed. Either that or if you have a table already where there's always going to be just one record in it add a new field 'DatabaseVersion' to it.
So for example if you check the version number, and find it's a version 1 database when the newest version should be version 3, you know which updates to perform on it.
You can use PRAGMA user_version to store the version number of the database and check if the database needs to be updated.

Using change table tracking

I need to use the changed table tracking feature of sql server 2008. I have enabled this on many tables. Now i have to write a sync program to transfer this data to another location.
My problem is how do i get only those tables whose data has changed without having to loop through all the changed tables list and checking each of them?
Try sys.CHANGE_TRACKING_TABLES (documented on MSDN here).
You'll have to use OBJECT_NAME to get the table name from the first column.

Query to identify the number of revisions made to a table

Is there any query which can return me the number of revisions made to the structure of a database table?
Secondly, how can I determine the number of pages (in terms of size) present in mdf or ldf files?
I think you need to create a trigger and store all changes to the table in a separate table. You can then use this table to get the revision history.
You can get last modify date or creation date of object in SQL Server.
For examle info on tables:
SELECT * FROM sys.objects WHERE type='U'
More info on msdn
Number of pages can be fetched from sys.database_files.
Check documentation
SQL Server doesn't keep track of changes so it can't tell you this.
The only way you may be able to do this is if you had a copy of all the scripts applied to the database.
In order to be able to capture this information in the future you should look at DDL triggers (v2005+) which will enable you to record changes.

Resources