If you call the same code again, you are creating an entirely new asset, replacing the previous. Thus any previous references will become invalid.
If you just want to update the asset, then first check if it exists. If it does not exist yet, create it. Otherwise load the asset (unless you already have an asset object reference), then modify the asset, then call SaveAssetIfDirty(playerData). Note that for ScriptableObjects when changing their properties through scripts you have to call EditorUtility.SetDirty(playerData) beforehand to mark it as “dirty”.
If you want to create multiple assets, then use AssetDatabase.GenerateUniqueAssetPath to ensure the path is unique before calling CreateAsset. This will create files named playerData (1) and so forth, effectively preventing you from overwriting existing assets.
Do not call Refresh() UNLESS you create or modify assets WITHOUT using AssetDatabase methods (eg when using File.WriteAllBytes). All AssetDatabase methods internally ensure that the AssetDatabase is updated correspondingly.
Again, remove this! It’s utterly unnecessary. Devs just been putting it everywhere out of (bad) habit. There’s absolutely nothing that needs refreshing here.
Keep in mind that Refresh necessitates a call to UnloadUnusedResources eg effectively wiping any in-editor caching.